gpt4 book ai didi

powershell - $使用:var in Start-Job within Invoke-Command

转载 作者:行者123 更新时间:2023-12-03 18:23:27 32 4
gpt4 key购买 nike

我正在使用 Invoke-Command ,并在 -ScriptBlock 内我正在使用 Start-Job .我必须使用 $Using:varStart-Job但是 session 正在寻找本地 session 中声明的变量(在 Invoke-Command 之前声明)。这是我正在做的一个非常简短的例子:

Invoke-Command -ComputerName $computer -ScriptBlock {
$sourcePath = 'C:\Source'
$destPath = 'C:\dest.zip'
$compressionLevel = [System.IO.Compression.CompressionLevel]::Optimal
$includeBaseDirectory = $false
Start-Job -Name "compress_archive" -ScriptBlock {
Add-Type -AssemblyName System.IO.Compression.FileSystem
[System.IO.Compression.ZipFile]::CreateFromDirectory("$using:sourcePath","$using:destPathTemp",$using:compressionLevel,$using:includeBaseDirectory)
}
}

Invoke-Command : The value of the using variable '$using:sourcePath' cannot be retrieved because it has not been set in the local session.
At line:1 char:1
+ Invoke-Command -ComputerName vode-fbtest -ScriptBlock {
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [Invoke-Command], RuntimeException
+ FullyQualifiedErrorId : UsingVariableIsUndefined,Microsoft.PowerShell.Commands.InvokeCommandCommand

如果我省略 $usingStart-Job -ScriptBlock {} 中调用变量时然后我得到一个 Cannot find an overload for "CreateFromDirectory" and the argument count: "4".错误,因为变量未在该范围内定义。

有没有办法使用 $using对于远程 session 中的变量而不是本地变量,或者可能是我可以指定的另一个范围,从远程 session 中获取变量?我可以在 Invoke-Command 之前在本地声明这些变量解决这个问题,但由于变量包含动态值,这需要大量的工作(所有这些都在 foreach ($obj in $objects) 中,其数据是在远程计算机上检索的,所以我需要重构整个脚本,如果我无法完成这项工作)。

我在 Windows Server 2012 R2(源主机和调用命令的 -ComputerName 主机)上使用 PS v5.1,如果这有什么区别的话。

看着 this answer我看到您可以将变量暴露给较低级别​​的脚本块,但我需要从远程 session 中实际声明变量。该值需要来自运行远程 session 的计算机。您能否在远程 session 中以某种方式声明变量,使其可用于顶级脚本块中的脚本块?

最佳答案

PetSerAl ,就像以前无数次一样,在对这个问题的简短评论中提供了关键的指针:

你需要:

  • 使用 [scriptblock]::Create()创建要传递给 Start-Job 的脚本块动态,来自字符串
  • 制作 [scriptblock]::Create()调用内部Invoke-Command脚本块,因为只有这样才能确保其中声明的变量是 [scriptblock]::Create() 中引用的变量。 - 通过 $using: 创建的脚本块范围说明符。
  • 相比之下,如果您使用脚本块文字,{ ... }Start-Job ,正如您的尝试,$using:引用文献不指Invoke-Command脚本块的范围,但到 Invoke-Command 的调用者的范围内,即对代码可见的变量,使整体 Invoke-Command称呼。
  • 理想情况下,扩展$using:...引用将足够智能以处理嵌套范围,就像在这种情况下一样,但在 PowerShell Core 7.0.0-preview.3 中并非如此。

  • 警告 :正如 PetSerAl 指出的,如果您使用 Invoke-Command使用命令范围的临时 session (通过使用 -ComputerName 暗示) - 而不是之前使用 New-PSSession 创建的生命周期更长的 session 并传递给 Invoke-Command-Session - 后台作业在 Invoke-Command 时终止在它(可能)有机会完成之前,调用返回。虽然你可以用管道输入 Start-Job调用 ... | Receive-Job -Wait -AutoRemove ,只有在您开始多项工作时才值得。

    所以:
    Invoke-Command -ComputerName $computer -ScriptBlock {

    # Inside this remotely executing script block, define the variables
    # that the script block passed to Start-Job below will reference:
    $sourcePath = 'C:\Source'
    $destPath = 'C:\dest.zip'
    $compressionLevel = [System.IO.Compression.CompressionLevel]::Optimal
    $includeBaseDirectory = $false

    # Define the Start-Job script block as *literal* (here-)*string*, so as
    # to defer interpretation of the $using: references, and then
    # construct a script block from it using [scriptblock]::Create(), which
    # ties the $using: references to *this* scope.
    $jobSb = [scriptblock]::Create(
    @'
    Add-Type -AssemblyName System.IO.Compression.FileSystem
    [System.IO.Compression.ZipFile]::CreateFromDirectory("$using:sourcePath","$using:destPathTemp",$using:compressionLevel,$using:includeBaseDirectory)
    '@
    )

    Start-Job -Name "compress_archive" -ScriptBlock $jobSb

    }

    关于powershell - $使用:var in Start-Job within Invoke-Command,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57700435/

    32 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com