В предыдущей статье, я рассказал о том, как настроить выполнение команд на удаленных серверах. В показанном примере использовался одна пара логин\пароль для всех серверов. А что делать, если у нас много серверов и на каждом из них разные пароли да и к тому же они не находятся в одной сети? Выходов из этой ситуации можно найти много, но я нашел для себя оптимальный способ. Рассмотрим скрипт:
1 2 |
$credential=Get-Credential $credential.Password | ConvertFrom-SecureString |
или
1 2 3 |
$out = "c:\password.txt" $credential=Get-Credential $credential.Password | ConvertFrom-SecureString | Add-Content $out |
при выполнении этих двух скриптов (необходимо ввести в открывшимся окне логин и пароль) мы получим некую строку или на экран (первый скрипт) или в файл (второй скрипт). Данная строка будет не что иной как зашифрованный пароль, который вы ввели. Вот этот самый пароль мы и будем использовать далее. Теперь создадим файл и назовем его server_all.txt с таким содержанием:
1 2 3 |
Administrator;01000000d08c9ddf011.....7adb2;server1,server2 Administrator;01000000d08c9ddf011.....8fa35;server3,server7,server10,srv2 Administrator;01000000d08c9ddf011.....dea73;srv1 |
В этом файле я «обрезал» пароль, т.к. приводить его в полном варианте нет смысла. Заметьте, что у сервера с одинаковым паролем я объединил в одну строку. Это сделано умышленно для того, чтобы можно было выполнять команды параллельно на этих серверах. Далее пишем скрипт, который читает файл и выполняет одинаковые команды на этих серверах.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
cls $srv = Get-Content "x:\[path]\server_all.txt"; # Скрипт, который будем выполнять на удаленных серверах $script_txt = "Get-Process exp*" # Переводим его в "ScriptBlock" $script = $executioncontext.invokecommand.NewScriptBlock($script_txt) #Забиваем массивы с данными foreach ($var in $srv) { # проверяем на комментарий, если есть в строке #- значит это коментарий. # или пустую строку if (($var -notmatch "#") -and ($var.Length -ne 0)){ # разделим строку $tmp = $var -split ";" # преобразуем пароль $pass = $tmp[1] | ConvertTo-SecureString $cred = New-Object System.Management.Automation.PSCredential $tmp[0],$pass $s = $tmp[2] -split "," # создаем сессию $session = New-PSSession -ComputerName $s -Credential $cred # выполняем запрос (найдем процесс "explorer") $result = Invoke-Command -Session $session -ScriptBlock $script # Обработаем результат for ($i=0; $i -lt $result.Count; $i++){ Write-Host $result[$i].PSComputerName,"`t",$result[$i].Name } #Выходим из сессии. Remove-PSSession -Session $session } } |
Результат работы скрипта будет следующий:
1 2 3 4 5 6 7 |
server1 explorer server2 explorer server3 explorer server7 explorer server10 explorer srv2 explorer srv1 explorer |
Вот собственно и все.
Единственное на что хотелось бы обратить внимание, так это на то, что если перенести этот скрипт на другой компьютер (или запустить под другой учетной записью), то это работать не будет, т.к. пароли «привязываются» к учетной записи и компьютеру. И в этом есть плюс!