Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
powershell invoke命令使用多行内容更新文件的内容_Powershell_Invoke Command - Fatal编程技术网

powershell invoke命令使用多行内容更新文件的内容

powershell invoke命令使用多行内容更新文件的内容,powershell,invoke-command,Powershell,Invoke Command,我需要在多台服务器上的一组配置文件中更新服务器名称。我有一个快速的脚本来完成它,但我不想单独登录到每台服务器并将脚本移动到它的本地来运行它。所以我使用Invoke命令。获取文件内容并对其进行更新时一切正常,但当我尝试将新内容写回文件时,在设置的内容上出现PositionParameterNotFound错误。我想是因为它是多线的 下面是迭代文件并尝试将其写回的代码块: ForEach($file in $Files){ $content = Invoke-command -compute

我需要在多台服务器上的一组配置文件中更新服务器名称。我有一个快速的脚本来完成它,但我不想单独登录到每台服务器并将脚本移动到它的本地来运行它。所以我使用Invoke命令。获取文件内容并对其进行更新时一切正常,但当我尝试将新内容写回文件时,在设置的内容上出现PositionParameterNotFound错误。我想是因为它是多线的

下面是迭代文件并尝试将其写回的代码块:

ForEach($file in $Files){
    $content = Invoke-command -computerName $computerName -ScriptBlock {get-Content $args[0] -raw} -argumentlist $($file.FullName)
    $content = $content -replace $serverRegEx, $newServer
    Invoke-command -computerName $computerName -ScriptBlock {Set-Content -path $args[0] -value "$($args[1])"} -argumentList $($file.FullName) $content
}

如何将此多行内容传递回远程命令参数?

我认为您无意中将数组转换为带有$$args[1]的字符串。试试这个

Invoke-Command -ScriptBlock {
    ForEach($file in $using:Files){
        $content = get-Content $file.FullName
        $content = $content %{$_ -replace $serverRegEx,$newServer}
        Set-Content -path $file.FullName -value $content
    }
}
这是一个范围问题

如果未指定在远程会话中使用本地变量,则无法在远程会话中使用本地变量。这需要PowerShellv3+及更高版本

例如:

Invoke-Command -ComputerName Server01 -ScriptBlock {
   Write-Output The value of variable a is: $using:a
   Write-Output The value of variable b is: $using:b
}


Get-Help about_remote_variables -Full
长描述

可以在远程计算机上运行的命令中使用变量。 只需给变量赋值,然后在 价值所在地

默认情况下,假定远程命令中的变量已定义 在运行命令的会话中。也可以使用变量 在本地会话中定义的,但必须将其标识为 命令中的局部变量

使用局部变量

也可以在远程命令中使用局部变量,但必须 指示变量是在本地会话中定义的

从Windows PowerShell 3.0开始,您可以使用使用范围 用于在远程命令中标识局部变量的修饰符

Invoke command argumentList参数接受一个数组,在第二次使用Invoke命令时,只向argumentList传递一个参数$$file.FullName。$content变量作为单独的参数传递,以调用命令,而不是脚本块

通过将2个参数作为数组传递来修复此问题:

Invoke-command -computerName $computerName -ScriptBlock {Set-Content -path $args[0] -value "$($args[1])"} -argumentList @($($file.FullName),$content)

所以这里的问题很简单-ArgumentList接受对象数组,但不能作为数组传递。以下是您所拥有的:

Invoke-command -computerName $computerName -ScriptBlock {Set-Content -path $args[0] -value "$($args[1])"} -argumentList $($file.FullName) $content
我认为,以下是您对参数的意图:

-computerName = $computerName
-ScriptBlock = {Set-Content -path $args[0] -value "$($args[1])"}
-argumentList = $($file.FullName), $content
问题是$$file.FullName和$content之间没有逗号,因此它不会将它们视为对象数组,而是将$$file.FullName视为-argumentList的值,然后将$content视为一个单独的对象,试图将其作为位置参数进行计算,但它无法确定它可以是哪个位置参数。解决方案是在两个项目之间添加逗号:

Invoke-command -computerName $computerName -ScriptBlock {Set-Content -path $args[0] -value "$($args[1])"} -argumentList $($file.FullName),$content

这与你的问题没有直接关系。。。为什么要运行两次Invoke命令?您正在将内容拉过网络,对其进行更改,然后将其发回。一种更简单、更健壮的方法是将所有命令放在一个脚本块中,使用$Using:scope将$vars交给脚本块,然后在远程系统上运行整个过程。您问题的答案与我是PS新手这一事实有关。由于这是一个脚本,我需要在10台服务器中的每台服务器上运行一次,所以我的多次调用可能就足够了。。。但是我非常喜欢$using scope的想法,我无论如何都要尝试一下!实际上,您可以对每个系统进行尽可能少的调用命令调用。每一个都需要时间。。。对于很多系统来说,即使是一小部分时间加起来也很快。[咧嘴笑]另外,把它拉到本地盒子上,在本地盒子上处理,然后再把它送回远程盒子位本身就是一个慢动作。我知道这可能是愚蠢的事情。非常感谢。看起来你和zdan几乎同时回答了这个问题,但我认为你的答案是正确的,因为它似乎排在第一位。也就是说,我认为李戴利也在做一些事情。谢谢大家!!同意,数据传输越少越好,而且$using:scope也是一件好事。