Как совместить две петли foreach?

Я посмотрел, как объединить несколько команд с psexec, но ни один из методов не работает. Может быть, это потому, что я запускаю скрипт в PowerShell, а не cmd.exe?

Мне нужно создать учетные записи пользователей и добавить их в локальную группу администраторов на компьютерах, не входящих в домен (Windows 2003). Я получил следующий скрипт (который работает), но мне интересно, есть ли простой способ объединить два цикла foreach, так как он должен установить соединение psexec дважды для каждого сервера.

$username = Read-Host "User name:"
$password = Read-Host "Password:"
$fullname = Read-Host "Full name:"
$computers = Get-Content C:\Tools\scripts\ServerList.txt

foreach ($computer in $computers) {
    psexec \\$computer -u username -p password net user $username $password /add /fullname:""$fullname"" /comment:"Comment"
}

foreach ($computer in $computers) {
    psexec \\$computer -u username -p password net localgroup Administrators $username /add
}

Как я уже говорил, это выполняется в PowerShell. Серверы, на которых я его запускаю, - это серверы рабочей группы Windows 2003 без установленного PowerShell.

1 ответ

Решение

Как сказал @CIA, вы можете комбинировать циклы, просто запустив psexec дважды в одной петле.

$username = Read-Host "User name:"
$password = Read-Host "Password:"
$fullname = Read-Host "Full name:"
$computers = Get-Content C:\Tools\scripts\ServerList.txt

foreach ($computer in $computers) {
    psexec \\$computer -u username -p password net user $username $password /add /fullname:""$fullname"" /comment:"Comment"
    psexec \\$computer -u username -p password net localgroup Administrators     
}

Но похоже, что вы действительно спрашиваете, как запустить обе команды сети в одном psexec сессия.

$username = Read-Host "User name:"
$password = Read-Host "Password:"
$fullname = Read-Host "Full name:"
$computers = Get-Content C:\Tools\scripts\ServerList.txt

foreach ($computer in $computers) {
    psexec \\$computer -u username -p password net user $username $password ullname"" /comment:"Comment" ^&^& net localgroup Administrators     
}

Вы можете попробовать это таким образом, но я не уверен, что это сработает. && экранируется с помощью ^ так что это передается psexec вместо того, чтобы интерпретироваться локально, что бы запустить второй net командовать локально.

альтернатива

То, что вы могли бы сделать вместо этого, не использовать psexec и вообще используйте PowerShell Remoting. Он просто должен быть включен на каждой машине, к которой вы хотите подключиться. Я понимаю, что это может быть чем-то вроде предприятия, но оно того стоит, так как оно более универсально, и в основном это будущее.

Если вы находитесь в домене, вы даже можете использовать групповую политику для включения удаленного взаимодействия PowerShell (полное раскрытие: это моя статья).

Если вы это сделаете, ваш код будет выглядеть так:

$username = Read-Host "User name:"
$password = Read-Host "Password:"
$fullname = Read-Host "Full name:"
$computers = Get-Content C:\Tools\scripts\ServerList.txt

foreach ($computer in $computers) {
    Invoke-Command -ComputerName $computer -ArgumentList $username,$password,$fullname -ScriptBlock { param($u,$p,$f)
        # Everything in here is executed on the remote computer
        net user $u $p /add /fullname:""$f"" /comment:"Comment"
        net localgroup Administrators     
    }
}
Другие вопросы по тегам