How to export from foreach-object

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

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. :wink:

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

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

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. :wink:

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

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. :wink:

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

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

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 <String>]
[-All <Boolean>]
[<CommonParameters>]

Get-AzureADUser
[-All <Boolean>]
[-Top <Int32>]
[-Filter <String>]
[<CommonParameters>]

Unless my understanding of the information in help is incorrect?

Darren

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.

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?

Hmmm … I think that should be a good base … now it is practice, practice, practice … :wink:

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

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 :