从包含多个用户的循环创建Powershell对象

时间:2014-10-27 02:47:03

标签: arrays loops object powershell hashtable

我需要创建一个Powershell对象,数组或哈希表来存储用户列表和各种详细信息,这些是从CSV文件中提取的,并使用Get-ADUser进行定位。如下:

$userList = Import-CSV $CSVInputFile
$users = @{}
Foreach ($csvUser in $userList)
{
    $userSearchString = $csvUser | Select -ExpandProperty SamAccountName
    $currentUser = (Get-ADUser -Filter {SamAccountName -eq $userSearchString} `
        -Properties PasswordExpired,PasswordLastSet,EmailAddress |
            Where {$_.Enabled -eq "True"})

    If ($currentUser.EmailAddress -ne $null)
    {
        $currentUserEmailString = $csvUser | Select -ExpandProperty EmailAddress
        $currentUserEmailString = ($currentUserEmailString -as [string])
        $currentUser.EmailAddress = $currentUserEmailString
    }

    $Users = New-Object PSObject -Property @{
        DistinguishedName = $currentUser.DistinguishedName
        EmailAddress = $currentUser.EmailAddress    
        Enabled = $currentUser.Enabled          
        GivenName = $currentUser.GivenName       
        Name = $currentUser.Name
        PasswordExpired = $currentUser.PasswordExpired
        PasswordLastSet = $currentUser.PasswordLastSet
        SamAccountName = $currentUser.SamAccountName
        Surname = $currentUser.Surname
    }
    $Users
}

如何为循环的每次迭代添加每个用户的详细信息。

我想最终得到一个包含许多用户详细信息的对象,与直接来自Get-ADUser的输出相同:

Name        SamAccountName EmailAddress                    
----        -------------- ------------                    
User1       user1      user1@domain.com    
User2       user2      user2@domain.com                         
User3       user3      user3@domain.com

非常感谢任何帮助!

3 个答案:

答案 0 :(得分:2)

不确定我是否错过了这一点,但我发现你正在循环中构建一个自定义对象。我看到的唯一问题是你没有在每次循环后保留结果。相反,你正在摧毁对象的历史。

我会将$users的声明更改为数组$users = @(),而不是将用户哈希表填充到用户中,而是将当前对象添加到数组中。然后,您将拥有一组哈希表:

$Users += New-Object PSObject -Property @{...

然后你可以在循环之外的$Users输出行,你将拥有整个东西。然后你可以输出到Select来获得你想要的输出。

$Users | Select-Object name,SamAccountName,EmailAddress

但这种方法存在潜在的主要缺点。在数组上使用+=时,将为新元素创建新数组并调整其大小,并丢弃旧数组。这对较大的阵列具有巨大的性能影响。


更好的方法是利用管道。当您拥有更大的用户组时,这将提升性能。

Import-CSV $CSVInputFile | ForEach-Object{
    $userSearchString = $_.SamAccountName
    $currentUser = Get-ADUser -Filter {SamAccountName -eq $userSearchString} `
        -Properties PasswordExpired,PasswordLastSet,EmailAddress |
            Where {$_.Enabled -eq "True"}

    If ($currentUser.EmailAddress -ne $null){
        $currentUser.EmailAddress = $_.EmailAddress
    }

    [pscustomobject][ordered]@{
        DistinguishedName = $currentUser.DistinguishedName
        # ..... truncated 
        Surname = $currentUser.Surname
    }
}

现在您可以将其发送到类似Export-CSV的内容,或者将其保存到变量中。您的选择现在开放。 [pscustomobject][ordered]是PowerShell v3.0 +

中提供的类型加速器

答案 1 :(得分:1)

将$ users定义为Array

$users = @()

并将New-Object附加到$ Users。

$Users += New-Object

答案 2 :(得分:0)

不能相信你们两个人都在我面前!那好吧。 希望这无论如何都有帮助。

$userList = Import-CSV $CSVInputFile
$users = @()
Foreach ($csvUser in $userList)
{
$userSearchString = $csvUser | Select -ExpandProperty SamAccountName
$currentUser = (Get-ADUser -Filter {SamAccountName -eq $userSearchString} `
    -Properties PasswordExpired,PasswordLastSet,EmailAddress |
        Where {$_.Enabled -eq "True"})

If ($currentUser.EmailAddress -ne $null)
{
    $currentUserEmailString = $csvUser | Select -ExpandProperty EmailAddress
    $currentUserEmailString = ($currentUserEmailString -as [string])
    $currentUser.EmailAddress = $currentUserEmailString
}

#clears the properties of the previous object and starts collecting properties
$UserObj = New-Object PSObject
    Add-Member -InputObject $UserObj -MemberType NoteProperty -Name "DistinguishedName" -Value $($currentUser.DistinguishedName)
    Add-Member -InputObject $UserObj -MemberType NoteProperty -Name "EmailAddress" -Value $($currentUser.EmailAddress)    
    Add-Member -InputObject $UserObj -MemberType NoteProperty -Name "Enabled" -Value $($currentUser.Enabled)
    Add-Member -InputObject $UserObj -MemberType NoteProperty -Name "GivenName" -Value $($currentUser.GivenName)     
    Add-Member -InputObject $UserObj -MemberType NoteProperty -Name "UserName" -Value $($currentUser.Name)
    Add-Member -InputObject $UserObj -MemberType NoteProperty -Name "PasswordExpired" -Value $($currentUser.PasswordExpired)
    Add-Member -InputObject $UserObj -MemberType NoteProperty -Name "PasswordLastSet" -Value $($currentUser.PasswordLastSet)
    Add-Member -InputObject $UserObj -MemberType NoteProperty -Name "SamAccountName" -Value $($currentUser.SamAccountName) 
    Add-Member -InputObject $UserObj -MemberType NoteProperty -Name "Surname" -Value $($currentUser.Surname)

#saves the properties in an array that exists outside of the loop to preserve information beyond one interation
$users += $UserObj
 }

 $users | Format-Table -Property UserName,SamAccountName,EmailAddress