Invoke-Command导出变量不全问题及保留文件名的解决咨询
问题原因
原脚本的核心问题是:
- 远程脚本块中用
echo $A,$B,$C会将三个变量的值作为三个独立的输出对象返回给本地 - 管道到
ForEach-Object时,会循环处理这三个对象,每次调用Out-File时默认使用覆盖模式(而非追加) - 前两次写入的内容($A、$B的值)会被第三次的内容($C的值)覆盖,最终文件里只剩最后一个变量的值
另外,每个远程输出对象都会自动带上PSComputerName属性,$_.PSComputerName的读取逻辑是正常的,问题根源在文件覆盖上。
解决方案
要保留$_.PSComputerName命名文件的同时导出所有变量,核心是避免多次覆盖文件,以下是几种可行方案:
方案1:封装为自定义对象
将三个变量打包成一个自定义对象,远程仅返回一个对象,本地一次性写入所有内容:
Invoke-Command -ComputerName Server1 -ScriptBlock { [PSCustomObject]@{ 用户名 = $env:username 主机名 = hostname 用户域 = $env:userdomain } } | ForEach-Object { # 按需格式化输出内容 "用户名: $($_.用户名)`n主机名: $($_.主机名)`n用户域: $($_.用户域)" | Out-File "c:\temp\$($_.PSComputerName).txt" }
这种方式的优势是输出内容结构清晰,便于后续扩展或处理。
方案2:打包为数组输出
将三个变量放入一个数组,远程输出整个数组,本地一次性写入:
Invoke-Command -ComputerName Server1 -ScriptBlock { @($env:username, hostname, $env:userdomain) } | ForEach-Object { $_ | Out-File "c:\temp\$($_.PSComputerName).txt" }
此方式下ForEach-Object仅执行一次,数组内的三个值会依次写入文件,无覆盖问题。
方案3:使用追加模式(兼容原输出逻辑)
如果要保留原脚本的多对象输出逻辑,可给Out-File添加-Append参数,每次循环追加内容而非覆盖:
Invoke-Command -ComputerName Server1 -ScriptBlock { $A=$env:username;$B=hostname;$C=$env:userdomain;echo $A,$B,$C } | ForEach-Object { $_ | Out-File "c:\temp\$($_.PSComputerName).txt" -Append }
注意:此方式会多次打开/关闭文件,效率略低于前两种方案。
内容的提问来源于stack exchange,提问作者Johnny Cakes
相关产品推荐
相关产品推荐

