脚本块上的powershell循环



我正试图将对象集合中的一些信息导出到CSV文件中。

为此,我总是有以下管道:

 $users | < my filters/grouping/selects and expands> | Export-CSV ...

与其复制/粘贴这些行,我更希望有一个哈希表,其中CSV文件名作为关键字,<…>之间的部分作为值

所以我做了这个:

$scriptblocks = @{"NonCompliantMail"={ ? {-not ([bool]($_.mail -as [Net.Mail.MailAddress])) } };
              "NonCompliantSAM"= { ? { ($_.samaccountname.Trim().Length - $_.samaccountname.Length) -ne 0 }};
              "MissingSN" = { ? {[string]::IsNullOrWhiteSpace($_.sn) } };
              "MissingGivenName" = { ? {[string]::IsNullOrWhiteSpace($_.givenname) } };
              "TrimSN" = { ? { (-not ([string]::IsNullOrWhiteSpace($_.sn))) -and (($_.sn.Trim().Length - $_.sn.Length) -ne 0) } };
              "TrimGivenName" = { ? { (-not ([string]::IsNullOrWhiteSpace($_.givenname))) -and (($_.givenname.Trim().Length - $_.givenname.Length) -ne 0) } }
              "MultipleEmails" = { group-object mail |? { $_.Count -gt 1 } | select -ExpandProperty Group | select mail,samaccountname }
              }

我正试图这样执行它,但它不起作用:

$scriptblocks.getEnumerator() |% { $users | & $_.Value | Export-Csv -NoTypeInformation -Force -Encoding $encoding -Delimiter $delimiter -Path (Join-Path $scriptpath ($_.Key + ".csv")) } 

有什么想法吗?

谨致问候。JB

Ok,所以Switch是一个循环,它根据一组过滤器测试数组的每个记录。如果记录通过了筛选,它将针对以下脚本块运行。过滤器可以是文字匹配、RegEx匹配或类似于Where语句的脚本块。为了满足您的需求,我们将使用最后一个。看看这个例子,看看它是否实现了你想要的:

Switch($users){
    {-not ([bool]($_.mail -as [Net.Mail.MailAddress])) }{$_|Export-Csv -NoTypeInformation -Force -Encoding $encoding -Delimiter $delimiter -Path (Join-Path $scriptpath ("NonCompliantMail" + ".csv")) -append}
    {($_.samaccountname.Trim().Length - $_.samaccountname.Length) -ne 0 }{$_|Export-Csv -NoTypeInformation -Force -Encoding $encoding -Delimiter $delimiter -Path (Join-Path $scriptpath ("NonCompliantSAM" + ".csv")) -append}
    {[string]::IsNullOrWhiteSpace($_.sn) }{$_|Export-Csv -NoTypeInformation -Force -Encoding $encoding -Delimiter $delimiter -Path (Join-Path $scriptpath ("MissingSN" + ".csv")) -append}
    {[string]::IsNullOrWhiteSpace($_.givenname) }{$_|Export-Csv -NoTypeInformation -Force -Encoding $encoding -Delimiter $delimiter -Path (Join-Path $scriptpath ("MissingGivenName" + ".csv")) -append}
    {(-not ([string]::IsNullOrWhiteSpace($_.sn))) -and (($_.sn.Trim().Length - $_.sn.Length) -ne 0) }{$_|Export-Csv -NoTypeInformation -Force -Encoding $encoding -Delimiter $delimiter -Path (Join-Path $scriptpath ("TrimSN" + ".csv")) -append}
    {(-not ([string]::IsNullOrWhiteSpace($_.givenname))) -and (($_.givenname.Trim().Length - $_.givenname.Length) -ne 0) }{$_|Export-Csv -NoTypeInformation -Force -Encoding $encoding -Delimiter $delimiter -Path (Join-Path $scriptpath ("TrimGivenName" + ".csv")) -append}
}

这将通过开关运行每个用户,如果它符合任何条件,它将把它附加到关联的CSV文件中。

编辑:好的,你不喜欢Switch。如果你真的想在ForEach Object循环中执行这样的脚本块,你可以在脚本块中添加参数以允许管道数据,但这并不能完全解决你的问题。我一会儿就讲到。首先,让我们选择Group-Object mail选项,并将其设置为接受输入:

"MultipleEmails" = { group-object mail |? { $_.Count -eq 1 } | select -ExpandProperty Group | select mail,samaccountname }

成为

"MultipleEmails" = {Param([Parameter(ValueFromPipeline=$True)][Object[]]$Users);$Users| group-object mail |? { $_.Count -eq 1 } | select -ExpandProperty Group | select mail,samaccountname }

为此,我在脚本块的开头添加了Param([Parameter(ValueFromPipeline=$True)][Object[]]$Users);$Users|。您可以将其添加到每个脚本块的开头,它们都应该以类似的方式运行。

然后,我们必须强制将$users作为数组传递给它,方法是将其包装为:(,$users)
这允许:

(,$users)|& $scriptblocks["multipleemails"]

这提供了你期望的输出。剩下的就是把它放在$ScriptBlocks的ForEach中,同时跟踪你当前的脚本块:

$scriptblocks.keys|%{$sb=$_;(,$users)|& $scriptblocks["$sb"]}

它输出所有脚本块中的所有内容。你现在唯一的问题是,你没有办法指定要输出到什么CSV。但这至少回答了你最初的问题。

这种方法的问题是效率低下:对于每个输出文件,您必须对所有$用户循环一次。

另一种方法是使用switch语句来绕过这一点(下面是伪代码):

$file1 = "NonCompliantMail.csv"
$file2 = "NonCompliantSAM.csv"
$file3 = "MissingSN.csv"
$file4 = "MissingGivenName.csv"
$file5 = "TrimSN.csv"
$file6 = "TrimGivenName.csv"
$file7 = "UsersWhoDontMatchAnything.csv"
function WriteUserDataToFile
{
    param
    (
        $User,
        $OutFile
    )
    "Process the $User object to append to $OutFile"
}
switch ($users) 
{ 
    ("User matching criteria 1") {WriteUserDataToFile $_ $file1}
    ("User matching criteria 2") {WriteUserDataToFile $_ $file2} 
    ("User matching criteria 3") {WriteUserDataToFile $_ $file3} 
    ("User matching criteria 4") {WriteUserDataToFile $_ $file4} 
    ("User matching criteria 5") {WriteUserDataToFile $_ $file5}
    ("User matching criteria 6") {WriteUserDataToFile $_ $file6}
    default {WriteUserDataToFile $_ $file7}
}

因此,用户会根据您的标准逐一匹配,当匹配时,会调用将该用户的数据附加到该类型匹配的文件中的函数。

希望这是一个合适的建议。

相关内容

  • 没有找到相关文章

最新更新