【问题标题】:Powershell Foreach usage and syntaxPowershell Foreach 用法和语法
【发布时间】:2018-02-10 13:02:39
【问题描述】:

我正在尝试使用 csv 文件编写在活动目录中创建帐户的脚本。不幸的是,我通常是 PowerShell 和脚本的新手,并且在管理 foreach() 循环时面临困难,该循环旨在处理我导入的 csv 文档中的每一列。

我怀疑我不能像我一样在 foreach() 之后的一个块中定义我的变量,但我不确定并且希望得到一些指导。具体来说,代码的目的是读取一个 csv 文档,并将每个项目分配给一个变量,然后使用该变量创建一个具有这些值的服务帐户。

理想的情况是我可以创建一个包含数百行的 csv,执行脚本并以数百个匹配的服务帐户结束。

$SVC = (import-csv C:\users\me\desktop\Test.csv -header("Name", "Pass", "WhatDo", "Location", "Domain")) `
foreach($variable in %SVC) {

    $name = $SVC.Name
    $Pass = $SVC.Pass
    $WhatDo = $SVC.WhatDo
    $Location = $SVC.Location
    $Domain = $SVC.Domain


        New-ADuser `
            -Name $name `
            -AccountPassword (Convertto-SecureString $Pass -AsPlainText -Force) `
            -CannotChangePassword $true `
            -Description $WhatDo `
            -DisplayName $name `
            -Enabled $true `
            -GivenName $name `
            -PasswordNeverExpires $True `
            -Office $Location `
            -Path "OU=Service-Accounts, Ou=Accunts, OU=_CORP, DC=$Domain, DC=net" `
            -SamAccountName $name `
            -UserPrincipleName $name + "@" + $domain + ".net" `

        Start-Sleep -Seconds 15

    Get-ADUser `
        -Identity $name | Add-ADPrincipalGroupMembership `
        -MemberOf "Group1","Group2","Group3"  

    }

【问题讨论】:

  • 请描述您遇到的问题 - 否则您的问题可能会面临关闭:寻求调试帮助的问题(“为什么这段代码不起作用?”)必须包括所需的行为,具体问题或错误以及在问题本身中重现它所需的最短代码。没有明确问题陈述的问题对其他读者没有用处。请参阅:how to create a minimal, verifiable example。祝你好运!
  • foreach ($item in $SVC) - 但是网上有很多关于从csv、excel、txt等创建AD用户的例子……

标签: powershell csv variables foreach


【解决方案1】:

您的代码中有很多问题,而不仅仅是 foreach。

但让我们从这个开始:foreach ($variable in $SVC) 意味着$variable 将在您的循环中包含当前项目,但您在循环中访问$SVC 仍然指的是原始集合。 $variable 也不是一个好名字,所以你应该把它改成更有意义的名字。另外,你写的是%SVC而不是$SVC

您还经常使用反引号 (`),有时是错误的。仅当您的 cmdlet 调用跨越多行时才应使用它。在Import-Csv 的情况下,它不是,但最后有反引号。 New-ADUser 的最后一行也有一个。有些人更喜欢使用Parameter Splatting 而不是反引号,但这只是个人喜好问题。

考虑到您正在创建服务帐户,我会这样写第一部分:

$serviceAccounts = Import-Csv C:\users\me\desktop\Test.csv -Header Name,Pass,WhatDo,Location,Domain

foreach($serviceAccount in $serviceAccounts) {

然后在您的循环中,您可以通过$serviceAccount 访问各个属性:

$name = $serviceAccount.Name

另外,PowerShell 在使用双引号时会扩展变量,所以-UserPrincipleName 可以这样写:-UserPrincipleName "$name@$domain.net"

【讨论】:

  • 我对脚本非常陌生,感谢每一位帮助。感谢您的评论,因为它让我取得了一些立竿见影的进展,也帮助我更快地掌握了我正在做的事情的本质。
【解决方案2】:

我更喜欢使用 ForEach-Object 而不是 foreach。

应该是这样的:

$SVC = (Import-CSV C:\users\me\desktop\Test.csv -header("Name", "Pass", "WhatDo", "Location", "Domain")) 
$SVC | ForEach-Object {

        New-ADuser `
            -Name $_.Name `
            -AccountPassword (Convertto-SecureString $_.Pass -AsPlainText -Force) `
            -CannotChangePassword $true `
            -Description $_.WhatDo `
            -DisplayName $_.Name `
            -Enabled $true `
            -GivenName $_.Name `
            -PasswordNeverExpires $True `
            -Office $_.Location `
            -Path "OU=Service-Accounts, Ou=Accunts, OU=_CORP, DC=$Domain, DC=net" `
            -SamAccountName $_.Name `
            -UserPrincipleName $_.Name + "@" + $_.Domain + ".net" 

        Start-Sleep -Seconds 15

    Get-ADUser `
        -Identity $_.Name | Add-ADPrincipalGroupMembership `
        -MemberOf "Group1","Group2","Group3"  

    }

$_ 表示管道中的当前项目。 (在您的情况下,$SVC 是错误的变量。)它的代码更少,我认为这是一种更清洁的做事方式!

【讨论】:

  • 感谢您的建议。我需要我能得到的所有帮助,你的回答让我知道我哪里出了问题。干杯。
【解决方案3】:

$SVC 重命名为 $SVCs 然后 foreach ($SVC in $SVCs)

【讨论】:

    【解决方案4】:

    这是一个示例。(不要忘记分隔符)

    $csv = Import-Csv -Path C:\temp\csv.csv -Header "a","b","c" -Delimiter ";"
    foreach($row in $csv){
        $row.a
        $row.b
        $row.c
    }
    

    以下是 foreach 工作原理的更多示例: 看看https://ss64.com/ps/foreach.html

    Examples
    
    Loop through an array of strings:
    
     $trees = @("Alder","Ash","Birch","Cedar","Chestnut","Elm")
    
     foreach ($tree in $trees) {
       "$tree = " + $tree.length
     }
    
    Loop through a collection of the numbers, echo each number unless the number is 2:
    
     foreach ($num in 1,2,3,4,5) {
      if ($num -eq 2) { continue } ; $num
     }
    
    Loop through a collection of .txt files:
    
      foreach ($file in get-ChildItem *.txt) {
        Echo $file.name
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-27
      • 2018-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-17
      • 1970-01-01
      • 2022-10-21
      相关资源
      最近更新 更多