Help with basic script

Jeffrey Pascone 1 Reputation point
2022-06-15T15:32:26.097+00:00

Hi Everybody,
I definitely struggle with PowerShell, I am hoping somebody can help write this for me and I will analyze it and try and figure out the next.

Basically I want to be able to pull users from an OU and sub OU's and output to a csv along with the following information:

FirstName, LastName, User logon name (pre-Windows 2000) Second Field, then the next 3 columns are for groups call it Group A, Group B and Group C. If they are a member of this group it will be indicated by an X or YES.

Example:
First, Last, LogonName, X,,X

Hopefully that makes sense. Thanks for your assistance

Active Directory
Active Directory
A set of directory-based technologies included in Windows Server.
3,609 questions
Windows Server PowerShell
Windows Server PowerShell
Windows Server: A family of Microsoft server operating systems that support enterprise-level management, data storage, applications, and communications.PowerShell: A family of Microsoft task automation and configuration management frameworks consisting of a command-line shell and associated scripting language.
4,618 questions
No comments
{count} votes

3 answers

Sort by: Most helpful
  1. Rich Matheisen 35,031 Reputation points
    2022-06-16T14:40:59.897+00:00

    I'm not trying to devalue the answer that @Newbie Jones provided, but I've noticed that many folks seem to either favor "one-liners" or ignore PowerShell's ability to use pipelines to simplify coding and increase clarity and resort to techniques that are necessary in other programming languages. E.g., using intermediate variables to accumulate results.

    Here's the same code, by way of example, just written in a different way (it's not necessarily the most efficient, though):

    # Retrieve the distinguishedName for the groups in scope, as you can query this against the memberOf attribute for the user  
    $groupA = (Get-ADGroup "GroupA").distinguishedName  
    $groupB = (Get-ADGroup "GroupB").distinguishedName  
    $groupC = (Get-ADGroup "GroupC").distinguishedName  
          
    # memberOf is a list of the groups the user is a member of  
    # Use Search base to target OU, by default this will include sub OU's  
    Get-ADUser -Filter * -Properties memberOf, GivenName, Surname -SearchBase "OU=Test Users,OU=x,OU=y,DC=xx,DC=yy,DC=zz"  |  
        ForEach-Object {  
            $props = [ordered]@{  
                GivenName = $_.GivenName  
                Surname   = $_.Surname  
                GroupA    = If ($groupA -In $_.memberof) { "True" } else {"False"}  
                GroupB    = If ($groupB -In $_.memberof) { "True" } else {"False"}  
                GroupC    = If ($groupC -In $_.memberof) { "True" } else {"False"}  
            }  
            [PSCustomObject]$props  
        } | Export-Csv filename.csv -NoTypeInformation  
    

  2. Newbie Jones 1,171 Reputation points
    2022-06-16T11:00:36.34+00:00

    This is the basic logic.

    # Use Search base to target OU, by default this will include sub OU's  
    # memberOf is a list of the groups the user is a member of  
    $userList = Get-ADUser -Filter * -properties memberOf, GivenName, Surname -SearchBase "OU=Test Users,OU=x,OU=y,DC=xx,DC=yy,DC=zz"  
      
    # Retrieve the distinguishedName for the groups in scope, as you can query this against the memberOf attribute for the user  
    $groupA = (Get-ADGroup "GroupA").distinguishedName  
    $groupB = (Get-ADGroup "GroupB").distinguishedName  
    $groupC = (Get-ADGroup "GroupC").distinguishedName  
      
    #Initialise a variable to store the results  
    $results=@()  
      
    ForEach ($user in $userList) {  
      
        $inGroupA="False"  
        $inGroupB="False"  
        $inGroupC="False"  
      
        If ($groupA -In $user.memberof) {$inGroupA="True"}  
        If ($groupB -In $user.memberof) {$inGroupB="True"}          
        If ($groupC -In $user.memberof) {$inGroupC="True"}  
      
      
        $props = [ordered]@{  
            GivenName=$user.GivenName  
            Surname=$user.Surname  
            GroupA=$inGroupA  
            GroupB=$inGroupB  
            GroupC=$inGroupC  
            }  
      
            $results +=  New-Object -TypeName PSObject -property $props  
      
    }  
      
    $results | Export-CSV filename.csv -noTypeInformation  
    
    No comments

  3. Rich Matheisen 35,031 Reputation points
    2022-06-16T18:06:22.823+00:00

    I hope you didn't think I was singling you out -- I wasn't. It just seemed like your code (it was short, it works, etc.) was an example of non-Powershell thinking that I wanted to address.

    I began a programming career in 1964 using assembly language (on an IBM 1401 computer), then moved on to COBOL, FORTRAN, RPG (NOT "Role Playing Games!"), PL/1, a couple of proprietary languages similar to PL/1, C, C++, SmallTalk, and then with PERL (I see a lot of PERL's influence in PowerShell). It took me a long time to come to grips with PowerShell and its very different way of using a "pipeline". And, while PowerShell really isn't "object oriented" it's use of objects makes life easier (although it sometimes complicates things!).

    "One-Liners" are convenient for short, disposable, one-off tasks. However, if you intend to use the code more than once, avoid using shortcuts like "?" and "%" -- they really do confuse people -- in the code. I even advocate for using full cmdlet names instead of aliases (Select-Object instead of Select, Get-ChildItem instead of GCI, etc.). It isn't necessary to declare variables before populating them, but it's a good idea (and keep "scope" in mind!). Also, use "Set-PSDebug -Strict", at least while you're testing!