Невозможно присвоить значение переменной внутри Invoke-Command - PullRequest
1 голос
/ 27 января 2020

Это кажется странным, но я не могу присвоить значение переменной внутри Invoke-Command. Ниже приведен код, но при выводе $ targetComputerPath он просто пуст. Что не так?

foreach ($item in $computersPath){

    $computername = $item.Name
    $username = $item.UserID

    Write-Host computer $computername and user $username

    if (Test-Connection -ComputerName $computername -Count 1 -ErrorAction SilentlyContinue)
    {
        if ($((Get-Service WinRM -ComputerName $computername).Status) -eq "stopped")
        {
          (Get-Service WinRM -ComputerName $computername).Start()
        } 
        Invoke-Command -ComputerName $computername -ScriptBlock {

        if ($((Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion").ReleaseId) -eq "1903" ) 
            {
               $targetComputerPath = "\\"+$computername+"\c$\Users\"+$username+"\Desktop\"
               write-host "1903"
            } 
        else 
            {
              $targetComputerPath = "\\"+$computername+"\c$\Users\"+$username+"\Desktop\"
              write-host "something else"
            } 
        }
    }
    write-host $targetComputerPath
}

1 Ответ

2 голосов
/ 27 января 2020

Смысл WinRM в том, что вы берете блок скрипта и выполняете его на другом компьютере .

Ни одна из переменных, определенных вами в хост-скрипте, не будет доступна на удаленная машина.

Это становится более очевидным, когда вы отделяете «задачу», то есть блок скрипта, от Invoke-Command, например:

$task = {
    $version = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion"
    if ($version.ReleaseId -eq "1903") {
        # note that `$username` cannot be available here, it's never been defined!
        return "\\$env:COMPUTERNAME\c$\Users\$username\Desktop"
    } else {
        return "\\$env:COMPUTERNAME\c$\Users\$username\Desktop"
    } 
}

foreach ($item in $computersPath) {
    $computername = $item.Name
    $username = $item.UserID

    Write-Host computer $computername and user $username

    if (Test-Connection -ComputerName $computername -Count 1 -ErrorAction SilentlyContinue) {
        $winrm = Get-Service WinRM -ComputerName $computername
        if ($winrm.Status -eq "stopped") { $winrm.Start() }
        $targetComputerPath = Invoke-Command -ComputerName $computername -ScriptBlock $task
        Write-Host "The machine returned: $targetComputerPath"
    }
}

Как видите, вы можете возвращать значения из блока скрипта, и они будут доступны как возвращаемое значение Invoke-Command.

Если вы хотите передать аргументы в блок скрипта, этот поток говорит об этом: Как передать именованные параметры с помощью Invoke-Command?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...