2014-11-15 2 views
1

Я создал список объектов, $ LIST. Каждый объект в списке имеет несколько атрибутов, включая полное доменное имя и службы. FQDN - это полное имя сервера, а сервисы - это список служб, которые я хочу проверить на удаленном сервере.Powershell invoke-command, передающая объект

Начну с:

$LIST = <CALL to Module function to populate the server information> 

Далее идет вызов Invoke-Command

Invoke-Command -ComputerName $LIST.FQDN -ScriptBlock { 
Write-Host "Working on $($env:ComputerName)" 
    Get-Service 
} 

Но что мне нужно сделать, это передать список услуг, которые соответствуют -ComputerName , Я знаю, что могу использовать -ArgumentList и я попытался:

Invoke-Command -ComputerName $LIST.FQDN -ScriptBlock { 
    Param ([string[]] $ServiceList) 
    Write-Host "Working on $($env:ComputerName)" 
    ($ServiceList -split(",")).trim() | %{ 
     $svc =Get-Service $_ 
     $Svc 
    } 
} -ArgumentList $LIST.Services 

Но это проходит список всех услуг для каждого сервера. Я могу это сделать:

$LIST | %{ 
    $Server = $_ 

    Invoke-Command -ComputerName $Server.FQDN -ScriptBlock { 
     Param ([string[]] $ServiceList) 
     Write-Host "Working on $($env:ComputerName)" 
     ($ServiceList -split(",")).trim() | %{ 
      $svc =Get-Service $_ 
      $Svc 
     } 
    } -ArgumentList $($Server.SERVICES) 
} 

Но тогда я потеряю преимущество параллельности Invoke-Command Командлет.

Как передать список услуг для обрабатываемого конкретного компьютерного имени? .

+0

Вы посмотрели параметр -AsJob команды Invoke-Command? –

ответ

0

Если $ LIST [ «КОМПЬЮТЕР»] УСЛУГИ список возврата службы КОМПЬЮТЕР вы можете проверить в вашем ScriptBlock для каждого объекта passed..maybe Это, но не протестированы: (в псевдокоде)

Icm -comp $LIST.FQDN -Script { 
    Param($obj) 
     $c=$env:computername 
     $obj["$c"].services 
} -arg $LIST 
0

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

Если список услуг относится к каждому удаленному компьютеру и каждый раз, когда вы запускаете команды, вы можете просто сохранить этот параметр на каждом конечном компьютере в реестре или файле. В идеале вы настраиваете это с помощью диспетчера конфигурации, такого как DSC, Puppet или Chef.

Вы можете сбросить параметры на файлы на локальном компьютере и позволить каждому целевому компьютеру подключиться к сетевому ресурсу и получить файл, соответствующий его имени. Если подключение к общему сетевому ресурсу невозможно, то простой веб-сервис или соединение с базой данных будут другими способами, позволяющими каждому компьютеру получить список услуг.

Существуют ли группы целей, которые получат тот же список? Скажем, у вас есть 10 различных списков сервисов, каждый из которых отправляется в группу из 100 компьютеров. В этом случае, возможно, вы можете выбрать произвольный компьютер из каждой группы и отправить эти компьютеры одинаковой команде со всеми данными. Каждый компьютер, на который вы нацеливаетесь, затем определяет, в какой группе он находится, и распределяет идентичную команду для всех своих братьев и сестер. Это также будет способствовать увеличению параллелизма.

Или просто создайте один набор сервисов, объединяющий все списки услуг, отправляйте их на каждую машину и отфильтровывайте результаты, на основе которых вы хотите. Это может быть самым простым решением:

PS C:\WINDOWS\system32> $allServices = 'WerSvc','WinRM','ZeroConfigService','AnotherService' 

PS C:\WINDOWS\system32> Invoke-Command -ComputerName . -ScriptBlock { 
    Get-Service -Name $args -ErrorAction Ignore 
} -ArgumentList $allServices 

Status Name    DisplayName       PSComputerName                          
------ ----    -----------       --------------                          
Stopped WerSvc    Windows Error Reporting Service  localhost                           
Running WinRM    Windows Remote Management (WS-Manag... localhost                           
Running ZeroConfigService Intel(R) PROSet/Wireless Zero Confi... localhost  

будет просто игнорировать любые услуги, которые вы просили, которые не установлены на этой конкретной машине.

0

Для тестирования я создал два объекта, содержащих указатель на localhost, и список конкретных служб для проверки.Цель состоит в том, чтобы вызывать фоновые задания, которые будут выполняться удаленно и параллельно, и проверять предоставленный список служб.

Одна из ключевых частей в приведенном ниже скрипте - это сгенерированный массив для списка аргументов Invoke-Command, который содержит массив служб для связанного с ним компьютера. Остальное - это в значительной степени ваш код. Наконец, я использую Get-Job | Receive-Job для получения результата из заданий Invoke-Command.

$LIST = @() 

$Computer1 = New-Object PSObject -Property @{ 
     FQDN = "localhost"; 
     SERVICES = @() 
    } 
$Computer1.SERVICES += "W32Time" 
$Computer1.SERVICES += "vmms" 
$LIST += $Computer1 

$Computer2 = New-Object PSObject -Property @{ 
     FQDN = "localhost"; 
     SERVICES = @() 
    } 
$Computer2.SERVICES += "ShellHWDetection" 
$Computer2.SERVICES += "SharedAccess" 
$LIST += $Computer2 

$LIST | %{ 
    $Server = $_ 
    $arguments = @(,($Server.SERVICES)) 
    Invoke-Command -ComputerName $Server.FQDN -AsJob -ScriptBlock { 
     Param ([string[]]$ServiceList) 
     Write-Host "Working on $($env:ComputerName)" 
       ($ServiceList -split(",")).trim() | %{ 
      $svc =Get-Service $_ 
      $Svc 
     } 
    } -ArgumentList $arguments 
} 
Get-Job | Receive-Job 

Выход заключается в следующем:

Id  Name   PSJobTypeName State   HasMoreData  Location    Command     
--  ----   ------------- -----   -----------  --------    -------     
28  Job28   RemoteJob  Running  True   localhost    ...      
30  Job30   RemoteJob  Running  True   localhost    ...      
Working on CORSAIR-PC 

Status Name    DisplayName       PSComputerName                               
------ ----    -----------       --------------                               
Stopped W32Time   Windows Time       localhost                                
Running vmms    Hyper-V Virtual Machine Management  localhost                                
Working on CORSAIR-PC 
Running ShellHWDetection Shell Hardware Detection    localhost                                
Stopped SharedAccess  Internet Connection Sharing (ICS)  localhost 

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

Смежные вопросы