[英]Dynamically an add element to an array in PowerShell
我正在嘗試對AD運行查詢以提供用戶列表。 由於我們的組織將標記“ LastName,FirstName”添加到計算機對象的描述字段中,因此我也想列出每個用戶分配的計算機。 這是我到目前為止的內容:
$ADGroup = "SomeADGroup"
$UserList = Get-ADGroupMember -Identity $ADGroup -Recursive `
| Select SamAccountName `
| foreach-object {(Get-ADUser -Identity $_.SamAccountName `
| Select @{n='AssignedUser';e={$_.Surname + ", " + $_.GivenName}}).AssignedUser}
$Results = New-Object System.Collections.Generic.List[System.Object]
foreach ($User in $UserList)
{
$MachineList = @(((Get-ADComputer -Filter "Description -like `"*$User*`"" | Select Name).Name) -join $_ + ",").ToUpper()
foreach ($Machine in $MachineList)
{
$Results +=
@{
'User' = $User
'Machine' = $Machine
}
}
}
$Results | ForEach-Object { [pscustomobject] $_ } | Format-Table
結果是這樣的:
User Machine
---- -------
White, Scott W107175
Jones, Henry W107195
Flinstone, Fred L109531,W108812
由於可以為每位用戶分配多台計算機,因此我試圖找到一種向陣列動態添加“列”的方法,以便每個計算機名稱元素都位於列中。 最終,這將使導出到CSV更加容易。 我正在尋找類似於以下內容的輸出:
User Machine Machine2
---- ------- -------
White, Scott W107175
Jones, Henry W107195
Flinstone, Fred L109531 W108812
好的,因此您想向現有對象添加未知數量的屬性。 使用Add-Member
cmdlet並不難做到。 接下來,您只需要構造一個循環,以便添加這些屬性容易理解,我們可以使用For
循環來完成。 最后,您需要確保數組中的第一條記錄具有所有可能的屬性。 當我們到達那里時,我會再說明一點。
首先,我們獲得用戶。 我更改了您的內容,因為我嚴格反對將反引號用作換行符,因為反引號很容易被空白挫敗。 我還將$UserList
從字符串數組更改$UserList
對象數組,因為無論如何以后都需要對象。 我們仍然捕獲名字和姓氏,但是作為[PSCustomObject]
上的User
屬性。
$ADGroup = "SomeADGroup"
$UserList = Get-ADGroupMember -Identity $ADGroup -Recursive |
Select SamAccountName |
foreach-object {
Get-ADUser -Identity $_.SamAccountName |
Select @{n='User';e={$_.Surname + ", " + $_.GivenName}}
}
因此,現在我們有了具有一個屬性的對象數組。 現在我們遍歷整個過程,搜索計算機,然后將計算機捕獲為字符串數組。 那只是您已經修改過的代碼。
foreach ($User in $UserList)
{
$MachineList = Get-ADComputer -Filter {Description -like "*$($User.User)*"} | Select -ExpandProperty Name
現在是我們稍微改變一下的地方。 對於發現的每台機器,我們都需要向已經擁有的對象添加一個屬性。 因為我們不知道有多少個,所以我們可以使用For
循環並對屬性進行相應編號。
for($i=0;$i -le $MachineList.Count;$i++)
{
Add-Member -InputObject $User -NotePropertyName "Machine$($i+1)" -NotePropertyValue $MachineList[$i]
}
}
因此,現在$UserList
是一個對象數組,每個對象都有User
屬性,但是有許多適合該用戶的Machine#
屬性。 問題是PowerShell會根據數組中的第一個對象輸出對象數組。 因此,在您的示例中:
User Machine Machine2
---- ------- -------
White, Scott W107175
Jones, Henry W107195
Flinstone, Fred L109531 W108812
Machine2
列將永遠不會顯示,因為該屬性在Scott White的第一條記錄中不存在。 因此,為了解決這個問題,我們需要找出數組中任何給定對象的所有可能的屬性,並將所有缺失的屬性添加到第一條記錄中。 使用PowerShell中每個對象都具有的隱藏PSObject
屬性可以輕松完成此操作。
首先,我們獲得所有可能的屬性名稱的列表:
$AllProps = $UserList | ForEach{$_.PSObject.Properties.Name} | Select -Unique
然后,我們過濾掉第一個記錄上已經存在的所有屬性,然后再次使用Add-Member
cmdlet將剩下的所有內容作為新屬性添加到記錄中。
$AllProps |
Where{ $_ -notin $UserList[0].psobject.properties.name } |
ForEach{ Add-Member -InputObject $UserList[0] -NotePropertyName $_ -NotePropertyValue $null }
然后,除了輸出結果之外,別無所要做,因為自從我們創建了用戶列表以來,結果已經存儲在$UserList
,並且只需使用每個用戶的計算機更新該現有列表,而不是創建用戶列表,然后再創建一個新的列表。用戶加機器。
$UserList | Format-Table
您已經很了解“變量”問題了; 根本上你永遠不會寫
$User.Machine1
$User.Machine2
$User.Machine...
因為您不知道有多少台計算機,所以無法在代碼中寫入屬性名稱。 數組就是解決這個問題的方法,並且您的代碼中有一個變量引用了一個數組,其中包含所有機器。 然后,您的代碼就變得有意義,簡單,明智且有效,但是它與您的CSV夢想不符-因為您的數據不是CSV形的。
如果為每位用戶向每台計算機添加一個屬性,則某些用戶擁有一台計算機,而某些用戶則具有四台...,這會激起Format-Table
, ConvertTo-Csv
, Out-GridView
,因為他們采用了第一個對象他們將其視為模板,然后刪除不在第一個對象上的其他對象上的任何列。
因此,您必須執行TheMadTechnician的操作,然后回去向所有對象動態添加所有空白的MachineN屬性,並且如果您只是說“將有N列”,這將非常簡單。
然后,您可以對它們進行計數,而我得到了:
$ADGroup = "SomeADGroup"
$ColumnCount = 10
Get-ADGroupMember -Identity $ADGroup -Recursive | Get-ADUser | ForEach-Object {
$User = [ordered]@{ 'User' = $_.SurName + ", " + $_.GivenName }
$Machines = @((Get-ADComputer -Filter "Description -like '*$($User.User)*'").Name)
for ($i=0; $i -lt $ColumnCount; $i++)
{
$User["Machine$i"] = $Machines[$i]
}
[PSCustomObject]$User
} | ConvertTo-Csv
NB。 我依賴數組的超出范圍的行為。 如果需要避免這種情況,請在“計算機”列表的末尾添加10列空字符串作為緩沖區。
但是我仍然很想自己使用字符串操作混搭CSV格式,並且根本不遍歷對象,因為您不使用它們,因為它們“應該”被使用,而只是走了很長一段路制作正確的屬性只是為了扔掉它們以獲得CSV。
偏離主題,您的代碼非常復雜:
$UserList = Get-ADGroupMember -Identity $ADGroup -Recursive `
| Select SamAccountName `
| foreach-object {(Get-ADUser -Identity $_.SamAccountName `
| Select @{n='AssignedUser';e={$_.SurName + ", " + $_.GivenName}}).AssignedUser}
獲得AD組成員,然后以完全不執行任何操作的方式選擇SamAccountName,然后遍歷結果,而不是直接將其直接傳遞到Get-ADUser,這毫無用處,然后選擇一個計算所得的屬性,然后將其拋出離開並獲得價值。 代替:
Get-ADGroupMember -Identity $ADGroup -Recursive | Get-ADUser | ForEach-Object { $_.SurName + ', ' + $_.GivenName }
獲取組成員,獲取其AD用戶,然后根據這些結果計算您的字符串。
和
$Results = New-Object System.Collections.Generic.List[System.Object]
->
$Results = @()
或者,更好的是:
$Results = @()
foreach ($x in $y) {
$Results += ...
}
->
$Results = foreach ($x in y ) {
...
}
和在
| ForEach-Object { [pscustomobject] $_ } |
您...在制作它們時可以使它們成為PSCustomObject
,然后就不需要了。
$ADGroup = "Some AD Group"
$UserList = Get-ADGroupMember -Identity $ADGroup -Recursive | Get-ADUser
$Results = @()
$MaxMachineCount = 0
foreach ($User in $UserList)
{
if ($User.SurName -and $User.GivenName -ne $null)
{
$CurrentUser = [ordered]@{ 'User' = $User.SurName + ", " + $User.GivenName }
$MachineList = @(((Get-ADComputer -Filter "Description -like `"*$($CurrentUser.User)*`"") | Select -ExpandProperty Name))
for ($i=0; $i -lt $MachineList.Count; $i++)
{
$CurrentUser.Add("Machine $i","$($MachineList[$i].ToUpper())")
if ($MaxMachineCount -le $i) {$MaxMachineCount++}
}
$Results += [PSCustomObject]$CurrentUser
}
}
for ($i=0; $i -lt $MaxMachineCount; $i++){$Results[0] | Add-Member -Name "Machine $i" -Value $null -MemberType NoteProperty -ErrorAction Ignore}
$Results | Format-Table -AutoSize
最后的代碼Format-Table -AutoSize
也可以替代ConvertTo-CSV | Out-File "C:\\Some\\Directory\\File.csv"
ConvertTo-CSV | Out-File "C:\\Some\\Directory\\File.csv"
我添加了它以在結果中創建其他列。 以前,每個用戶最多只能顯示兩台計算機。 現在,該腳本將為每個用戶返回所有分配的計算機。
for ($i=0; $i -lt $MachineList.Count; $i++){$Results[0] | Add-Member -Name "Machine $i" -Value $null -MemberType NoteProperty -ErrorAction Ignore
這是我的結果:
User Machine 0 Machine 1 Machine 2 Machine 3 Machine 4 Machine 5 Machine 6 Machine 7 Machine 8
---- --------- --------- --------- --------- --------- --------- --------- --------- ---------
Froeman, Abe L110911
Maclatchie, Matthew W109370 L108518
White, Walter V999100 L107800 V999109 V999108 V999107 V999102 V999106 V999105 V999101
感謝@TessellatingHeckler和@TheMadTechnician的輸入。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.