Функциональный блок Invoke-Command

Я пытаюсь вызвать функциональный блок, который не требует дополнительных аргументов в командлете Invoke-Command.

$hostList = (Read-Host "Enter IP addresses/hostnames of hosts you want to connect to (Comma seperated)").Split(',');
    foreach($_ in $hostList){
       Invoke-Command -ComputerName $_ -Credential Administrator -ScriptBlock{$Function:PCInfo}
    }

Мой функциональный блок выглядит примерно так (в целях тестирования):

Function PCInfo{
       $winVersion = gwmi -class Win32_OperatingSystem | select Caption,Version,CSName,OSArchitecture
       $processorInfo = gwmi -class Win32_Processor | select Name,Manufacturer,MaxClockSpeed
       $diskInfo = gwmi -class Win32_LogicalDisk | select @{Label=’Drive Letter’;Expression={$_.DeviceId}}, @{Label=’Size (GB)’;Expression={"{0:N2}" -f ($_.Size/1GB)}}, @{Label=’Free Space (GB)’;Expression={"{0:N2}" -f($_.freespace/1GB)}} 
       $routingTable = gwmi win32_IP4RouteTable | select Destination,Mask,@{Label=’Next Hop’;Expression={$_.NextHop}} -uniq | format-table 
       $timeObject = gwmi -class Win32_OperatingSystem
}

У меня возникают две проблемы при использовании этого кода:

  1. Это не приводит ни к какому результату. Я искал SO и нашел похожие вопросы, но я могу найти только похожие сценарии, в которых функция использует дополнительные аргументы. Поскольку это автономный тип функции, я не могу понять, почему она не работает.

  2. При запуске этого скрипта от имени обычного пользователя появляется всплывающее окно с учетными данными. Я заполняю учетные данные администратора, но получаю следующую ошибку:

Запрос учетных данных

[127.0.0.1] Не удалось подключиться к удаленному серверу 127.0.0.1 со следующим сообщением об ошибке: Отказано в доступе.*

Интересно, почему это происходит, если я заполняю (локальные) учетные данные администратора?


person Community    schedule 17.09.2013    source источник


Ответы (1)


На первый вопрос: область вашего удаленного скрипта не будет понимать локальные функции или переменные. Возможно, вместо этого попробуйте это:

# Create a ScriptBlock to contain the content.
$script = 
{ 
   # WinVersion
   $WinVersion = gwmi -class Win32_OperatingSystem | select Caption,Version,CSName,OSArchitecture
   # ProcessorInfo
   $ProcessorInfo = gwmi -class Win32_Processor | select Name,Manufacturer,MaxClockSpeed
   # DiskInfo
   $DiskInfo = gwmi -class Win32_LogicalDisk | select @{Label=’Drive Letter’;Expression={$_.DeviceId}}, @{Label=’Size (GB)’;Expression={"{0:N2}" -f ($_.Size/1GB)}}, @{Label=’Free Space (GB)’;Expression={"{0:N2}" -f($_.freespace/1GB)}} 
   # RoutingTable
   $RoutingTable = gwmi win32_IP4RouteTable | select Destination,Mask,@{Label=’Next Hop’;Expression={$_.NextHop}} -uniq 
   # TimeObject
   $TimeObject = gwmi -class Win32_OperatingSystem 

   # Write all results to ScriptBlock's output
   $WinVersion, $ProcessorInfo, $DiskInfo, $RoutingTable, $TimeObject
}

$hostList = (Read-Host "Enter IP Address or Host (Comma separated)").Split(',');
foreach($_ in $hostList)
{
   $output = Invoke-Command -ComputerName $_ -Credential Administrator -ScriptBlock $script

   #Output can be used in this scope before the next iteration of the loop.
   $output
}

Вы также можете определить функцию в своем удаленном скрипте или передать содержимое в качестве аргумента, но это казалось более прагматичным, поскольку ScriptBlock это просто контейнер для этих вызовов gwmi. Вам решать, как обрабатывать или использовать эти выходные данные после их получения. Не забудьте проверить код на наличие заметок о области действия!

Что касается вашего второго вопроса... см. этот вопрос суперпользователя для удаленного взаимодействия PowerShell в качестве пользователя, не являющегося администратором. Вам потребуется настроить удаленное взаимодействие без прав администратора (в качестве администратора) с локального компьютера, даже если у вас есть учетные данные администратора для доступа к удаленному компьютеру.

person Anthony Neace    schedule 17.09.2013
comment
Ну, я должен добавить; Моя фактическая функция - намного больше строк, чем только эта. Я обновлю ОП. Я посмотрю на ссылку, которую вы разместили в то же время! - person ; 17.09.2013
comment
@SiemHermans Только что увидел ваше редактирование, это все еще должно работать для вас. Вы не делаете ничего необычного со своей функцией, поэтому она по сути является контейнером для этого содержимого — точно так же, как ScriptBlock. Если вы планируете использовать этот вывод в своем скрипте, вам, вероятно, следует сохранить его в переменной. Я отредактирую свой пост с примером. - person Anthony Neace; 17.09.2013
comment
Я переписал операторы gwmi, чтобы они принимали переменные для $computername и $credentials, тем самым обойдя первоначальную проблему Invoke-Command. Однако остается вторая проблема. Я включил локальную учетную запись администратора, выполнил шаги, указанные в вашей ссылке, и добавил всех в группу пользователей удаленного управления. Ошибка все еще стоит. Я должен что-то упустить... - person ; 17.09.2013