2016-04-17 2 views
0

У меня есть два файла. Первая содержит имена хостов (Computers.txt), а вторая содержит SID (SID.txt). Я хочу использовать Get-Content и foreach для выполнения команды на каждом компьютере с соответствующим SID для изменения реестра.Get-Content и foreach в двух файлах

Возьмем, к примеру, ПК 1 (первая строка Computers.txt с первой строкой SID.txt) и ПК 2 (вторая строка Computers.txt со второй строкой SID.txt).

$Computer = Get-Content D:\Downloads\computers.txt 
$SID = Get-Content D:\Downloads\SID.txt 
foreach ($pc in $Computer) 
{ 
    Invoke-Command -ComputerName $pc {New-Item HKEY_USERS:\$SID -Name -Vaue} 
} 

ответ

1
  • Использование foreach -loop не дает вам текущее LINENUMBER так что невозможно, чтобы получить ту же строку из МОСРГА списка. Вы должны использовать while - или for -loop, чтобы создать индекс, который увеличивается на единицу для каждого прогона, чтобы вы знали «текущую строку».

  • Нет HKEY_USERS: PSDrive. Вам нужно получить к нему доступ с помощью реестра-провайдера, как Registry::HKEY_USERS\

  • переменных в локальном масштабе (напр. $currentsid) не доступны внутри Invoke-Command -scriptblock, поскольку он выполняется на удаленном компьютере. Вы можете передать его с помощью -ArgumentList $yourlocalvariable и позвонить ему $args[0] (или положить param ($sid) в начале скриптового блока). С PS 3.0+ это намного проще, поскольку вы можете использовать область использования ($using:currentsid) в своем скрипте.

Пример:

$Computers = Get-Content D:\Downloads\computers.txt 
$SIDs = Get-Content D:\Downloads\SID.txt 

#Runs one time for each value in computers and sets a variable $i to the current index (linenumer-1 since arrays start at index 0) 
for($i=0; $i -lt $Computers.Length; $i++) { 
    #Get computer on line i 
    $currentpc = $Computers[$i] 
    #Get sid on line i 
    $currentsid = $SIDs[$i] 

    #Invoke remote command and pass in currentsid 
    Invoke-Command -ComputerName $currentpc -ScriptBlock { param($sid) New-Item "REGISTRY::HKEY_USERS\$sid" -Name "SomeKeyName" } -ArgumentList $curentsid 

    #PS3.0+ with using-scope: 
    #Invoke-Command -ComputerName $currentpc -ScriptBlock { New-Item "REGISTRY::HKEY_USERS\$using:currentsid" -Name "SomeKeyName" } 
} 

Однострочник:

0..($Computers.Length-1) | ForEach-Object { Invoke-Command -ComputerName $Computers[$_] -ScriptBlock { param($sid) New-Item REGISTRY::HKEY_USERS\$sid -Name "SomeKeyName" } -ArgumentList $SIDs[$_] } 

На боковой ноте: Использование двух файлов с номерами соответствия линии является плохой идеей. Что делать, если у comptuers больше строк, чем SID? Вы должны использовать CSV-файл, который отображает компьютер и SID. Ex ..

input.csv:

Computer,SID 
PC1,S-1-5-21-123123-123213 
PC2,S-1-5-21-123123-123214 
PC3,S-1-5-21-123123-123215 

Это безопаснее, проще в обслуживании, и вы можете использовать его как это:

Import-Csv input.csv | ForEach-Object { 
    Invoke-Command -ComputerName $_.Computer -ScriptBlock { param($sid) New-Item REGISTRY::HKEY_USERS\$sid -Name "SomeKeyName" } -ArgumentList $_.SID 
} 
+0

хорошо, я постараюсь прокомментировать результаты , спасибо – Dfcrespo

+0

Это прекрасно работает. Спасибо y – Dfcrespo

+0

Отлично. Не забудьте отметить выбранный ответ, используя галочку слева от ответа, чтобы вопрос был закрыт. :-) –

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