为什么powershell认为$dir是null在设置位置而不是在写入输出时?
$command = {
param($dir)
Set-Location $dir
Write-Output $dir
}
# run the command as administrator
Start-Process powershell -Verb RunAs -ArgumentList "-NoExit -Command $command 'C:\inetpub\wwwroot'"
Run Code Online (Sandbox Code Playgroud)
这导致以下输出:
Set-Location : Cannot process argument because the value of argument "path" is null. Change the value of argument
"path" to a non-null value.
At line:3 char:2
+ Set-Location $dir
+ ~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Set-Location], PSArgumentNullException
+ FullyQualifiedErrorId : ArgumentNull,Microsoft.PowerShell.Commands.SetLocationCommand
C:\inetpub\wwwroot
Run Code Online (Sandbox Code Playgroud)
我也试过:
$command = {
param($dir)
Set-Location $dir
Write-Output $dir
}
$outerCommand = {
Invoke-Command -ScriptBlock $command -ArgumentList 'C:\inetpub\wwwroot'
}
# run the command as administrator
Start-Process powershell -Verb RunAs -ArgumentList "-NoExit -Command $outerCommand"
Run Code Online (Sandbox Code Playgroud)
但后来我得到了:
Invoke-Command : Cannot validate argument on parameter 'ScriptBlock'. The argument is null. Provide a valid value for
the argument, and then try running the command again.
At line:2 char:30
+ Invoke-Command -ScriptBlock $command 'C:\inetpub\wwwroot'
+ ~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Invoke-Command], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.InvokeCommandCommand
Run Code Online (Sandbox Code Playgroud)
可能的线索:如果我设置一个局部变量而不是使用参数,它会完美地工作:
$command = {
$dir = 'C:\inetpub\wwwroot'
Set-Location $dir
Write-Output $dir
}
# run the command as administrator
Start-Process powershell -Verb RunAs -ArgumentList "-NoExit -Command $command"
Run Code Online (Sandbox Code Playgroud)
类似的 Q/As 并没有完全回答我的问题:
Start-Process,我需要以管理员身份运行)Invoke-Command而不是Start-Process)$command是一个脚本块( { ... }) 并且将脚本块字符串化会导致其文字内容,不包括封闭的{和}。
因此,您的可扩展字符串"-NoExit -Command $command 'C:\inetpub\wwwroot'"从字面上扩展为以下字符串 - 请注意{ ... }原始脚本块周围的缺失:
-NoExit -Command
param($dir)
Set-Location $dir
Write-Output $dir
'C:\inetpub\wwwroot'
Run Code Online (Sandbox Code Playgroud)
由于丢失了封闭的{and },由powershell产生的新进程Start-Process悄悄地忽略了孤立param($dir)语句,并且,鉴于新进程因此没有$dir变量(假设它也不是自动变量),命令失败,因为Set-Location $dir等同于到Set-Location $null,失败。[1]
请注意,您永远不能像这样将脚本块传递给Start-Process所有参数必须是字符串,因为只有字符串才能传递给外部进程。
在您的情况下,最简单的解决方案是:
将$command您的可扩展字符串中的参考附上{ ... }以补偿由于字符串化而造成的此外壳的损失
并预先&确保在新进程中调用生成的脚本块。
这是一个有效的解决方案:
Start-Process powershell -Verb RunAs -ArgumentList `
"-NoExit -Command & { $command } 'C:\inetpub\wwwroot'"
Run Code Online (Sandbox Code Playgroud)
重要提示:虽然手头的特定脚本块不需要,但具有嵌入"字符的"..."任何脚本块。不会被目标进程正确解析为整个字符串的一部分;为了防止这种情况,它们必须被转义为\",这是外部程序所期望的 - 包括通过其 CLI 的 PowerShell:
# Script block with embedded " chars.
$command = {
param($dir)
Set-Location $dir
"Current dir: $dir"
}
# Embed the script block with " escaped as \"
Start-Process powershell -Verb RunAs -ArgumentList `
"-NoExit -Command & { $($command -replace '"', '\"') } 'C:\inetpub\wwwroot'"
Run Code Online (Sandbox Code Playgroud)
[1] 在Windows PowerShell 中失败;在 PowerShell Core 中,相当于Set-Location 不带参数,更改为当前用户的主文件夹。
| 归档时间: |
|
| 查看次数: |
2577 次 |
| 最近记录: |