Export-Csv 从全局变量到局部变量

Export-Csv from global to local variable

我试图将脚本的输出存储在 foreach 循环中的局部变量中,然后将其从远程会话导出到本地系统上的 CSV:

$cred = Get-Credential domain\username
$TargetSession = Get-Content C:\test\computers.txt

foreach ($Computer in $TargetSession) {
    $Session = New-PSSession $Computer -Credential $cred
    $result = Invoke-Command -Session $Session -ArgumentList $computer -ScriptBlock {
        $Database = "secaudit"

        #SMTP Relay Server
        $SMTPServer = "smtp.mail.net"
        $SqlQuery = "xp_fixeddrives"
        $SqlConnection = New-Object System.Data.SqlClient.SqlConnection
        $SqlConnection.ConnectionString = "Data Source=$computer;Initial Catalog=$Database;Integrated Security = True"
        $SqlCmd = New-Object System.Data.SqlClient.SqlCommand
        $SqlCmd.CommandText = $SqlQuery
        $SqlCmd.Connection = $SqlConnection
        $SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
        $SqlAdapter.SelectCommand = $SqlCmd
        $DataSet = New-Object System.Data.DataSet
        $nRecs = $SqlAdapter.Fill($DataSet)
        $nRecs | Out-Null
        $objTable = $DataSet.Tables[0]
    } 

    $final = Invoke-Command -Session $Session -ScriptBlock {
        $result
    } | Export-Csv -Path c:\test\output_space.csv -NoTypeInformation

    Remove-PSSession -Session $Session
}

但我收到以下错误:

Export-Csv : Cannot bind argument to parameter 'InputObject' because it is null.
At C:\test\drivespace_mail.ps1:33 char:75
+ $final= Invoke-Command -Session $Session -ScriptBlock{$result}| Export-Csv <<<<  -path c:\test\output_space.csv -NoTypeInformation
   + CategoryInfo : InvalidData: (:) [Export-Csv],ParameterBindingValidationException
   + FullyQualifiedErrorId ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands`.ExportCsvCommand

脚本块内的变量与脚本块外的变量在不同的范围内,所以如果您有这样的代码:

$foo = 'something'
Invoke-Command -ScriptBlock { $foo }

你有两个不同的变量 $foo,脚本块中的一个是空的,因为它从未被初始化。

您可以在脚本块中使用外部作用域中的变量,方法是将它们作为参数传递到脚本块中:

Invoke-Command -ScriptBlock {
  Param($foo)
  $foo
} -ArgumentList $foo

或通过 using: scope modifier:

Invoke-Command -ScriptBlock { $using:foo }

但是,您的第一个 Invoke-Command 从来没有 outputs/returns 任何东西(所有输出都分配给变量,因此在调用 returns 时丢失)。因为没有分配给 $result ,所以即使您在第二个脚本块中使变量可访问,您也会得到同样的错误。

此外,您的双命令调用不必要地复杂。只需使用这样的管道:

Get-Content 'C:\test\computers.txt' | ForEach-Object {
    Invoke-Command -Computer $_ -ScriptBlock {
        Param($computer)
        $Database = 'secaudit'
        ...
        $DataSet.Tables[0]
    } -ArgumentList $_ -Credential $cred
} | Export-Csv -Path 'C:\test\output_space.csv' -NoType