将 guid 和路径作为变量传递给 bcdedit /set

时间:2021-07-03 01:06:15

标签: powershell automation powershell-remoting bcdedit

我需要运行这 4 个命令才能将新映像启动到设备中:

bcdedit /copy {current} /d "Describe"
bcdedit /set {guid} osdevice vhd=somepath 
bcdedit /set {guid} device vhd=somepath
bcdedit /default {$guid} 

为了自动化我的脚本,我想提取作为第一个命令的输出返回的 guid/标识符,并将其作为参数传递给其他 3 个命令。 现在,我是这样做的:

$guid = Invoke-Command -ComputerName $comp -Credential $cred -ScriptBlock {cmd /c "bcdedit /copy {current} /d "Describe""}

#output
#$guid = This entry was successfully copied to {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}

$guid = $guid.Replace("This entry was successfully copied to {","")
$guid = $guid.Replace("}","")

$path1 = "xxx/xxxx/...."

#passing the guid and path as inputs
Invoke-Command -ComputerName $comp -Credential $cred -ScriptBlock {cmd /c "bcdedit /set {$guid} osdevice vhd=$path1"}
Invoke-Command -ComputerName $comp -Credential $cred -ScriptBlock {cmd /c "bcdedit /set {$guid} device vhd=$path1"}
Invoke-Command -ComputerName $comp -Credential $cred -ScriptBlock {cmd /c "bcdedit /default {$guid} "}

但是,每次出现错误时:

元素数据类型无法识别,或不适用于指定的条目。 运行“bcdedit /?”用于命令行帮助。 未找到元素

当我在 UI 中手动复制和粘贴路径时,这可以正常工作,但我不确定如何实现自动化。

1 个答案:

答案 0 :(得分:1)

  • this answer 中对您先前问题的解释,无需使用 cmd /c 来调用 bcdedit - 所需的只是引用 包含 {} 的文字参数,因为这些字符在不带引号的情况下使用时,在 PowerShell 中具有特殊含义。

    • 通过 cmd /c 调用不仅效率低下(尽管在实践中几乎没有影响),而且还会引入令人头疼的引用问题。[1]
  • 传递给 Invoke-Command -ComputerName ... 的脚本块远程执行,因此无法访问调用者的变量;从调用者的范围中包含变量值的最简单方法是通过 $using: 范围(请参阅 this answer)。

因此:

$guid = Invoke-Command -ComputerName $comp -Credential $cred -ScriptBlock { 
  bcdedit /copy '{current}' /d "Describe" 
}

# Extract the GUID from the success message, which has the form
# "This entry was successfully copied to {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}"
$guid = '{' + ($guid -split '[{}]')[1] + '}'

$path1 = "xxx/xxxx/...."

# Passing the guid and path as inputs, which must
# be done via the $using: scope.
Invoke-Command -ComputerName $comp -Credential $cred -ScriptBlock { 
  bcdedit /set $using:guid osdevice vhd=$using:path1
  bcdedit /set $using:guid vhd=$using:path1
  bcdedit /default $using:guid
}

[1] 例如,cmd /c "bcdedit /copy {current} /d "Describe"" 并不像您认为的那样工作;它必须是 cmd /c "bcdedit /copy {current} /d `"Describe`""