PowerShell中的最后一个foreach循环失败但前一个循环工作正常

时间:2017-04-14 14:37:08

标签: powershell

此脚本旨在帮助从一个域迁移到另一个域。我正在寻找所有AD安全组,然后我拉出每个组的成员并创建一个文本文件,其中包含该组的名称和该组的成员。

然后,我想创建一组新的文本文件,以便在每个组的用户MailNickName字段中包含这些信息,这称为NID(新ID)。我使用此MailNickName为新域存储NID,以便我可以将NID推送到新域中的相应群组。

在下面的脚本中,除了最后一个foreach循环外,一切都有效,不确定原因;它看起来是正确的,我在互联网上搜索答案,但没有理由说这不起作用。

我没有收到任何错误,但$b变量最终与$iGroup变量的值相同。此外,永远不会创建NID的新文本文件。

$iScript = "GetADGroups"
$StrPath = "C:\Temp\$iScript"
$StrFile = "$StrPath\$iScript.txt"
if(!(Test-Path $StrPath)){New-Item -ItemType directory -Path $StrPath}

$OU1 = "OU=Users,OU=OC,DC=domain,DC=com"
$OU2 = "OU=Users,OU=AMC,DC=domain,DC=com"
$OU3 = "OU=Users,OU=FI,DC=domain,DC=com"

Get-ADGroup -Filter 'GroupCategory -eq "Security"' -SearchBase $OU1 | ft name -HideTableHeaders | Out-File "$strFile"
Get-ADGroup -Filter 'GroupCategory -eq "Security"' -SearchBase $OU2 | ft name -HideTableHeaders | Out-File "$StrFile" -Append
Get-ADGroup -Filter 'GroupCategory -eq "Security"' -SearchBase $OU3 | ft name -HideTableHeaders | Out-File "$StrFile" -Append

(GC $StrFile) | ? {$_.trim() -ne ""} | Set-Content $StrFile
$Groups = (GC $StrFile)
$Groups | foreach{$_.TrimEnd()} | Set-Content $StrFile
$Groups = (GC $StrFile)

foreach($Member in $Groups){
    foreach($a in $Member){
        if(Test-Path "$StrPath\$a.Members.txt"){Remove-Item -Path "$StrPath\$a.Members.txt" -Force}
        Write-Host $iMember
        $iMember = Get-ADGroupMember "$a" | Select-Object sAMAccountName
        $iMember | ft -HideTableHeaders | Out-File "$StrPath\$a.Members.txt" -Append
        (GC "$StrPath\$a.Members.txt") | ? {$_.trim() -ne ""} | set-content "$StrPath\$a.Members.txt"
        (GC "$StrPath\$a.Members.txt") | foreach{$_.TrimEnd()} | Set-Content "$StrPath\$a.Members.txt"
        GCI "$StrPath\$a.Members.txt" | where {$_.Length -lt 1} | Remove-Item
        }
    }

$GroupName = (GCI "$StrPath\*.Members.txt" -Name)
foreach($iGroup in $GroupName){
    foreach($b in $iGroup){
        if(Test-Path "$StrPath\$b.NID.txt"){Remove-Item -Path "$StrPath\$b.NID.txt" -Force}
        Write-Host $b
        Get-ADUser -filter {sAMAccountName -eq "$b"} -Properties MailNickName | Select-Object MailNickName | Set-Content "$StrPath\$b.NID.txt"
        }
    }

1 个答案:

答案 0 :(得分:1)

  1. 您的foreach($b in $iGroup)循环一个项目,它们将始终相等。演示:

    $GroupName = "Group1.Members.txt","Group2.Members.txt","Group3.Members.txt"
    foreach($iGroup in $GroupName){
        foreach($b in $iGroup){
            Write-Host $b
         }
    }
    Group1.Members.txt
    Group2.Members.txt
    Group3.Members.txt
    

    当然,您不想阅读该文件?实施例

    foreach($Group in (GCI "$StrPath\*.Members.txt")){
        Write-Host $Group.Name
        foreach($User in (Get-Content -Path $Group.FullName)){
            Write-Host $User
         }
    }
    
  2. 导出和导入对象时,您很少使用Format-* - cmdlet,因为它们用于在控制台中显示数据并中断对象。因此,您最终必须每次都清理文本文件。我强烈推荐使用Export-CSVImport-CSV或自定义文本文件的CSV文件(如果是,请使用Select-Object -ExpandProperty Name仅显示组名)。

  3. 您在浪费时间阅读,修改和删除文件。我会把它重写成这样的东西:

    $iScript = "GetADGroups"
    $StrPath = "C:\Temp\$iScript"
    $StrFile = "$StrPath\$iScript.txt"
    #-Force to also create missing parents-folders
    if(!(Test-Path $StrPath)){New-Item -ItemType Directory -Path $StrPath -Force}
    
    $OUs = "OU=Users,OU=OC,DC=domain,DC=com", "OU=Users,OU=AMC,DC=domain,DC=com", "OU=Users,OU=FI,DC=domain,DC=com"
    $Groups = $OUs | Foreach-Object { Get-ADGroup -Filter 'GroupCategory -eq "Security"' -SearchBase $_ }
    #Save groupnames to file if you need them
    $Groups | Select-Object -ExpandProperty Name | Set-Content -Path $StrFile
    
    foreach($group in $Groups){
        Write-Host $group
        $members = @(Get-ADGroupMember -Identity $group)
    
        #If group contains members
        if($members.Count -gt 0) {
            #Create list of members
            $members | Select-Object -ExpandProperty sAMAccountName | Set-Content -Path "$StrPath\$group.Members.txt"
    
            #Create list with new IDs (is the other list necessary?)
            $members | Get-ADUser -Properties MailNickName | Select-Object -ExpandProperty MailNickName | Set-Content -Path "$StrPath\$group.NID.txt"
        }
    }
    

    最好将成员和NID列表合并到单个csv文件中,其中username和mailnickname使用单行链接。例如:

    #If group contains members
    if($members.Count -gt 0) {
        #Create csv-list of members with current username (samaccountname) and new id (mailnickname)
        $members | Get-ADUser -Properties MailNickName | Select-Object -Property sAMAccountName, MailNickName | Export-CSV -Path "$StrPath\$group.csv" -NoTypeInformation
    }
    

    或者更进一步,只需要一个包含所有组成员身份的csv文件。

    $iScript = "GetADGroups"
    $StrPath = "C:\Temp\$iScript"
    $StrFile = "$StrPath\$iScript.txt"
    
    $OUs = "OU=Users,OU=OC,DC=domain,DC=com", "OU=Users,OU=AMC,DC=domain,DC=com", "OU=Users,OU=FI,DC=domain,DC=com"
    $Groups = $OUs | Foreach-Object { Get-ADGroup -Filter 'GroupCategory -eq "Security"' -SearchBase $_ }
    #Save groupnames to file if you need them (if you're migrating empty groups)
    $Groups | Select-Object -ExpandProperty Name | Set-Content -Path $StrFile
    
    $Groups | Foreach-Object {
        $group = $_
        Write-Host $group
        Get-ADGroupMember -Identity $group |
        #Getting ADUser object to get missing property
        Get-ADUser -Properties MailNickName |
        Select-Object -Property @{n="Group";e={$group}}, sAMAccountName, MailNickName
    } | Export-CSV -Path "$StrPath\GroupMembers.csv" -NoTypeInformation
    

    您的CSV看起来像这样,在将成员添加到新组时,可以使用Import-CSV轻松导入,分组等等:

    Group,sAMAccountName,MailNickName
    Group1,user1,mailnickforuser1
    Group2,user1,mailnickforuser1
    Group2,user2,mailnickforuser2