Переменная с подстановочными знаками - PullRequest
0 голосов
/ 04 марта 2019

Этот код, похоже, возвращает все аренды DHCP, а не конкретный компьютер, который я ищу.Если я удалю строку Read-Host и вместо этого вставлю строку поиска вручную, как показано ниже: Where-Object {$_.HostName -like "*sdub*", тогда я получу совпадение с компьютером.

$HOSTNAME = Read-Host 'Input part of the computer name'
$HOSTLIST = Invoke-Command -ComputerName services02 -ArgumentList $HOSTNAME -Scriptblock {
    Get-DHCPServerv4scope | Get-DHCPServerv4Lease | Where-Object {
        $_.HostName -like "*$($Args[0])*" 
    }
}
foreach($HOSTINLIST in $HOSTLIST) {
    $HOSTINLIST | Format-Table -Property HostName, IPAddress, 
        @{Label="Online"; Expression={Test-Connection $HOSTINLIST.IPAddress -Count 1 -Quiet}}
}

Ответы [ 2 ]

0 голосов
/ 04 марта 2019

Как показано в вашем собственном ответе , PSv3 + использует специальную $using: область - которая позволяет включать значения переменных из области действия вызывающего в блоки сценариев, выполненные удаленно - решает вашу проблему .См. Нижний раздел, если вам нужно решить проблему в PowerShell v2.


Что касается , почему ваш оригинальный подход, основанный на -ArgumentList, не работал :

В то время как блок сценария, переданный Invoke-Command , видит все, что было передано через -ArgumentList в его немедленном объеме, любые команды в нем, которые запускают черезблок сценария ({ ... }) - даже если они технически работают в той же области , как в случае с Where-Object и ForEach-Object - do not см. тот же массив $Args, если только он явно не передан - то есть not опция с блоками сценария, передаваемыми в такие командлеты, как Where-Objectи ForEach-Object.

Упрощенный пример (в котором даже не используется удаленное взаимодействие, что является следствием исходной проблемы):

Invoke-Command { 

  # OK - sees 'foo', because $Args reflects what was passed via -ArgumentList
  "0: $($Args[0])"

  # !! Does NOT see foo', because the script block executed by ForEach-Object
  # !! - even though it runs in the same scope - has its own $Args definition
  # !! and given that NO arguments were passed to *it*, the $Args that it
  # !! sees is *empty* (an empty array).
  'bar' | ForEach-Object { "1: $($Args[0])" } 

} -ArgumentList 'foo'

Выше приведено:

0: foo
1:

, который показывает, что блок скрипта, переданный в ForEach-Object, больше не видит то же значение $Args, что и область верхнего уровня блока скрипта, переданного to Invoke-Command.


Вы можете заставить свой оригинальный подход работать следующим образом (что необходимо, если вы застряли в PowerShell v2):

Invoke-Command { 

  # OK - sees 'foo', because $Args reflects what was passed via -ArgumentList
  "0: $($Args[0])"

  # Save the original $Args array...
  $ArgsSaved = $Args

  # ... and reference the *saved* array in the script block.
  'bar' | ForEach-Object { "1: $($ArgsSaved[0])" } 

} -ArgumentList 'foo'
0 голосов
/ 04 марта 2019

Проблема решена с помощью $ с использованием: HostName вместо передачи переменной через -ArgumentList:

$HostName = Read-Host 'Input part of the computer name'
$HostList = Invoke-Command -ComputerName services02 -Scriptblock { Get-DHCPServerv4scope | Get-DHCPServerv4Lease | Where-Object {$_.HostName -like "*$using:HostName*" } }
foreach($HostInList in $HostList) {
$HostInList | Format-Table -Property HostName, IPAddress, @{Label="Online"; Expression={Test-Connection $HostInList.IPAddress -Count 1 -Quiet}}
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...