2017-02-16 14 views
2

私はユーザーのリストを私に与えるためにADに対してクエリを実行しようとしています。私たちの組織より。タグ "LastName、FirstName"をコンピュータオブジェクトの説明フィールドに追加し、ユーザごとに割り当てられたマシンもリストしたいと考えています。これは私がこれまで持っているものです。Powershellは動的に要素を配列に追加します

$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 

任意の助けをいただければ幸いです。

答えて

0
$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 

私は自分の結果に追加の列を作成するには、これを追加しました。以前は、ユーザーあたり最大2台のマシンしか表示されませんでした。スクリプトは、ユーザーごとに割り当てられたすべてのマシンを返します。

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に感謝します。

3

いいえ、既存のオブジェクトに不明な数のプロパティを追加する必要があります。 Add-Memberコマンドレットを使用するのはそれほど難しいことではありません。次にループを構造化して、それらのプロパティを追加するのがわかりやすくなるようにする必要があります。Forループを使用するとできます。最後に、配列の最初のレコードにすべての潜在的なプロパティがあることを確認する必要があります。私たちがそこに着くともう少し説明します。

まず、ユーザーを取得します。あなたが少し持っていたものを変更しました。なぜなら、それが空白で簡単に挫折するので、私はバック継続を行継続文字として使用することに厳密に反対しているからです。また、あとでオブジェクトを追加したいので、$UserListを文字列の配列からオブジェクトの配列に変更しました。最初と最後の名前を取得しますが、Userプロパティは[PSCustomObject]です。

$ADGroup = "SomeADGroup" 
$UserList = Get-ADGroupMember -Identity $ADGroup -Recursive | 
    Select SamAccountName | 
    foreach-object { 
     Get-ADUser -Identity $_.SamAccountName | 
      Select @{n='User';e={$_.Surname + ", " + $_.GivenName}} 
    } 

ここでは、1つのプロパティを持つオブジェクトの配列があります。今度はそれをループし、コンピュータの検索を行い、文字列の配列としてマシンをキャプチャします。これはあなたがすでに持っていたコードからわずかに変更されたコードです。

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列が表示されることはありません。だから、これを回避するには、配列内の任意のオブジェクトのすべての可能なプロパティを見つけ出し、最初のレコードに欠落しているものを追加する必要があります。これは、PowerShellの各オブジェクトにある秘密のPSObjectプロパティを使用して簡単に実行できます。

まず、我々はすべての可能なプロパティ名のリストを取得:

$AllProps = $UserList | ForEach{$_.PSObject.Properties.Name} | Select -Unique 

その後、我々は最初のレコードにすでに任意のプロパティをフィルタリングし、左の何がAdd-Memberコマンドレットを使用して、新しいプロパティとしてレコードに追加されます再び。

$AllProps | 
    Where{ $_ -notin $UserList[0].psobject.properties.name } | 
    ForEach{ Add-Member -InputObject $UserList[0] -NotePropertyName $_ -NotePropertyValue $null } 

が次に何の関係もありませんが、我々はユーザーの私たちのリストを作ったので、すでに$UserListに格納されており、単純に更新された出力結果、その各ユーザーのマシンのリストを既存のではなく、ユーザーのリストを作るよりも、ユーザとマシンの新しいリストを作成します。

$UserList | Format-Table 
+0

ありがとうございました!私は今日後でこれをテストします。配列の最初のユーザーの空の列に戻って追加するといいですね。おそらくそれを捕まえたことはないでしょう。 –

0

あなたはここで「可変変数」質問領域にうまくいます。基本的にあなたがそこにあるどのように多くのマシンがわからないので、あなたは

$User.Machine1 
$User.Machine2 
$User.Machine... 

を書くことはないので、あなたのコード内でプロパティ名を書き込むことはできません。配列はこれに対する答えです。配列内のすべてのマシンを参照する1つの変数がコード内にあります。あなたのコードは理にかなっていますが、それは簡単で賢明で効果的ですが、あなたのデータがCSV形式ではないため、あなたのCSVの夢と一致しません。

各ユーザーにマシンごとにプロパティを追加する場合、1台のマシンと4とのいくつかと、一部のユーザーを取得...そして、彼らは、彼らが最初に目に物を取るので、それは、Format-TableConvertTo-CsvOut-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} 

あなたは結果以上、あなたループ、その後、あなたは絶対に何もしない方法で、SAMアカウント名を選択し、ADグループメンバーを取得それを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] $_ } | 

であなたは...あなたはその後、それらPSCustomObjectsを作ることができますこれは必要ありません。コード Format-Table -AutoSizeのエンドピースも ConvertTo-CSV | Out-File "C:\Some\Directory\File.csv"

の代わりに使用することができる

+0

畳んだコードは私の初期の段階からPowershellにダブリングでリサイクルされました。私はより洗練されたコードに感謝します。私はそれを試してみましょう。 –

関連する問題