How to export from foreach-object

Welcome Forums General PowerShell Q&A How to export from foreach-object

This topic contains 12 replies, has 3 voices, and was last updated by

js
 
Participant
1 month ago.

  • Author
    Posts
  • #170899

    Participant
    Topics: 11
    Replies: 20
    Points: 132
    Rank: Participant

    Hi Everyone,

     

    I am trying to export the output of creating new azure AD users to a csv file.

     

    This is what I've come up with so far:

     

    #

    $users = Import-Csv "C:\test\users.csv"

    #

    #Create Password

     

    Function Generate-Password(){

    Param($max = 1)

    For ($i = 0; $i -lt $max; $i++){

    $pw = Get-Random -Count 1 -InputObject ((65..72)+(74..75)+(77..78)+(80..90)) | % -begin {$UC=$null} -process {$UC += [char]$_} -end {$UC}

    $pw += Get-Random -Count 2 -InputObject (97..122) | % -begin {$LC=$null} -process {$LC += [char]$_} -end {$LC}

    $pw += Get-Random -Count 2 -InputObject (48..57) | % -begin {$NB=$null} -process {$NB += [char]$_} -end {$NB}

    $pw += Get-Random -Count 3 -InputObject (97..122) | % -begin {$LC=$null} -process {$LC += [char]$_} -end {$LC}

     

    write-output $pw

    }

    }

     

    #Create new AzureAD User

    $users = Import-Csv "C:\test\users.csv"

     

    $mail = ($user.Firstname + "." + $user.lastname).ToLower()

    $PasswordProfile = New-Object -TypeName Microsoft.Open.AzureAD.Model.PasswordProfile

    $password = Generate-Password 1

    $PasswordProfile.Password = $password

     

    $users | ForEach-Object {New-AzureADUser -GivenName $user.Firstname `

    -MailNickName $mail`

    -UserPrincipalName $user.Username`

    -DisplayName $user.DisplayName`

    -Surname $user.lastname`

    -JobTitle $user.JobTitle`

    -Department $user.Department`

    -AccountEnabled $true `

    -PasswordProfile $PasswordProfile} | Export-Csv -Path "C:\test\output.csv" -NoTypeInformation

     

    I did originally try to use a foreach loop but that does not use the pipeline to get the data out. Hence why I'm using the ForEach-Object commandlet. I think my issue is that the variables prior to running the ForEach-Object need to be parsed but don't think I'm doing it right.

     

    Any help much appreciated.

     

    Darren

  • #170905

    Participant
    Topics: 1
    Replies: 1530
    Points: 2,591
    Helping Hand
    Rank: Community Hero

    Please read the information in the very first post of this forum: Read Me Before Posting! You'll be Glad You Did! ... especially the how to post code. 😉

    I'd recommend something like this:

    Function New-Password {
        Param($max = 1)
        For ($i = 0; $i -lt $max; $i++) {
            $pw = Get-Random -Count 1 -InputObject ((65..72) + (74..75) + (77..78) + (80..90)) | ForEach-Object -begin { $UC = $null } -process { $UC += [char]$_ } -end { $UC }
            $pw += Get-Random -Count 2 -InputObject (97..122) | ForEach-Object -begin { $LC = $null } -process { $LC += [char]$_ } -end { $LC }
            $pw += Get-Random -Count 2 -InputObject (48..57) | ForEach-Object -begin { $NB = $null } -process { $NB += [char]$_ } -end { $NB }
            $pw += Get-Random -Count 3 -InputObject (97..122) | ForEach-Object -begin { $LC = $null } -process { $LC += [char]$_ } -end { $LC }
            write-output $pw
        }
    }
     
    $UserList = Import-Csv 'C:\test\users.csv'
    $Result = foreach ($User in $UserList) {
        $mail = ($user.Firstname + "." + $user.lastname).ToLower()
        $PasswordProfile = New-Object -TypeName Microsoft.Open.AzureAD.Model.PasswordProfile
        $password = New-Password 1
        $PasswordProfile.Password = $password
        $Params = @{
            GivenName         = $user.Firstname
            MailNickName      = $mail
            UserPrincipalName = $user.Username
            DisplayName       = $user.DisplayName
            Surname           = $user.lastname
            JobTitle          = $user.JobTitle
            Department        = $user.Department
            AccountEnabled    = $true
            PasswordProfile   = $PasswordProfile
        }
        New-AzureADUser  @Params
        [PSCustomObject]@{
            GivenName         = $user.Firstname
            MailNickName      = $mail
            UserPrincipalName = $user.Username
            DisplayName       = $user.DisplayName
            Surname           = $user.lastname
            JobTitle          = $user.JobTitle
            Department        = $user.Department
            AccountEnabled    = $true
            PasswordProfile   = $password
        }
    }
    $Result | Export-Csv -Path 'C:\test\output.csv' -NoTypeInformation
  • #170908

    Participant
    Topics: 11
    Replies: 20
    Points: 132
    Rank: Participant

    Hello Olaf,

    thank you for your quick response.

    will that also collect the passwords that I tried to randomly create or do I need to merge the outputs somehow?

    Kind regards, Darren

  • #170914

    Participant
    Topics: 1
    Replies: 1530
    Points: 2,591
    Helping Hand
    Rank: Community Hero

    I don't have any experience with Azure AD cmdlets yet but it should output whatever the cmdlet's output is ... if you like to explicitly output something particular you might add an additional PSCustomObject ( I updated the code example above ). Of course you should try the code in a lab environment – not in your production environment – to verify it does what you expect. 😉

  • #170923

    Participant
    Topics: 11
    Replies: 20
    Points: 132
    Rank: Participant

    Hi Olaf,

    thank you for your reply.

    I've done some quick testing and it returns these column headings:

    GivenName, MailNickName, UserPrincipalName, DisplayName, Surname, JobTitle, Department, AccountEnabled, PasswordProfile

    The column titled PasswordProfile, returns the value "Class" for every user.

    Is there a way of adding another column with the randomly generated password?

    Kind Regards, Darren

  • #170956

    Participant
    Topics: 1
    Replies: 1530
    Points: 2,591
    Helping Hand
    Rank: Community Hero

    You're creating the actual password as the variable $password and you're adding the actual password as a subproperty of $PasswordProfile with the name Password – so that's $PasswordProfile.Password. If you want to output this you have to either output the content of the variable $password or the subproperty $PasswordProfile.Password ... that's totally up to you. 😉

    • #171073

      Participant
      Topics: 11
      Replies: 20
      Points: 132
      Rank: Participant

      Hi Olaf,
      Thanks for your response.
      To Summarise:
      The password is being created in $password
      The password is being added to $passwordProfile with the name "Password"

      OUTPUT
      $password
      or
      $PasswordProfile.Password

      OPTIONS
      Get-Variable – gets variables displays on console, can be piped to external output.
      Write-Output – displays on console
      Output-File – sends output to a file.
      Export-csv – directs to a csv file (prefered)

      TEST
      $PasswordProfile.Password | Export-csv/path/file.csv

      RESULT
      "Length"
      "8"

      I suppose the question is, why does the csv only contain this data and not the passwords?

      How can I get the passwords into the csv file?

      Kind regards, Darren

  • #171076

    Participant
    Topics: 1
    Replies: 1530
    Points: 2,591
    Helping Hand
    Rank: Community Hero

    Hmmm ... I don't know what exactly the problem for you is but I tested the following code and it works just as expected:

    Function New-Password {
        Param($max = 1)
        For ($i = 0; $i -lt $max; $i++) {
            $pw = Get-Random -Count 1 -InputObject ((65..72) + (74..75) + (77..78) + (80..90)) | ForEach-Object -begin { $UC = $null } -process { $UC += [char]$_ } -end { $UC }
            $pw += Get-Random -Count 2 -InputObject (97..122) | ForEach-Object -begin { $LC = $null } -process { $LC += [char]$_ } -end { $LC }
            $pw += Get-Random -Count 2 -InputObject (48..57) | ForEach-Object -begin { $NB = $null } -process { $NB += [char]$_ } -end { $NB }
            $pw += Get-Random -Count 3 -InputObject (97..122) | ForEach-Object -begin { $LC = $null } -process { $LC += [char]$_ } -end { $LC }
            write-output $pw
        }
    }
    
    $List = Get-ADUser -SearchBase '.........' -Filter *
    $Result = foreach ($User in $List) {
        $Password = New-Password 1
        [PSCustomObject]@{
            GivenName         = $user.Givenname
            UserPrincipalName = $user.UserPrincipalName
            DisplayName       = $user.Name
            Surname           = $user.Surname
            PasswordProfile   = $Password
        }
    }
    $Result | Format-Table -AutoSize
    • #171079

      Participant
      Topics: 11
      Replies: 20
      Points: 132
      Rank: Participant

      Olaf,

      As I'm using Get-AzureADUser instead of Get-ADUser I amended line 12 as follows:

      $List = Get-AzureADUser -SearchString '.........' -Filter *

      When I run this, here is the result:

      $Result | Format-Table -AutoSize | Export-Csv -Path 'C:\path\file.csv' -NoTypeInformation
      Get-AzureADUser : Parameter set cannot be resolved using the specified named parameters.
      At line:12 char:9
      + $List = Get-AzureADUser -SearchString '.........' -Filter *
      + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      + CategoryInfo : InvalidArgument: (:) [Get-AzureADUser], ParameterBindingException
      + FullyQualifiedErrorId : AmbiguousParameterSet,Microsoft.Open.AzureAD16.PowerShell.GetUser

      The reason I changed Line 12 is that 'SearchBase' is not valid with Get-AzureADUser where as 'SearchString' is.

      The message in the result "Parameter set cannot be resolved using the specified named parameters."  I've checked the online help for Get-AzureADUser and those parameters are valid but not at the same time:

      Get-AzureADUser
      [-SearchString ]
      [-All ]
      []
      
      Get-AzureADUser
      [-All ]
      [-Top ]
      [-Filter ]
      []

      Unless my understanding of the information in help is incorrect?

      Darren

  • #171094

    Participant
    Topics: 1
    Replies: 1530
    Points: 2,591
    Helping Hand
    Rank: Community Hero

    That code snippet was just to show that the password will be outputted as expected.

    I recommend to make a step back and start to learn the very basics of Powershell. This way you're able to understand the help you get in forums like this and you can adapt the code to your specific environment.

    • #171151

      Participant
      Topics: 11
      Replies: 20
      Points: 132
      Rank: Participant

      Hi Olaf,

      thank you for your help with this thread.

      It is much appreciated.

      I have been through a few books including Dons PowerShell in a Month of lunches.

      Is there another resource which would be of help?

  • #171157

    Participant
    Topics: 1
    Replies: 1530
    Points: 2,591
    Helping Hand
    Rank: Community Hero

    Hmmm ... I think that should be a good base ... now it is practice, practice, practice ... 😉

    Edit: I updated the code again. It should output the password as well.

  • #171166
    js

    Participant
    Topics: 25
    Replies: 678
    Points: 1,629
    Helping Hand
    Rank: Community Hero

    Here's a trick to pipe from foreach () :

    PS C:\users\me> & { foreach ($i in dir | where extension -eq .txt) { $i } } | measure
    
    
    Count    : 98
    Average  :
    Sum      :
    Maximum  :
    Minimum  :
    Property :
    
    
    

You must be logged in to reply to this topic.