PowerShell Remoting Ускорение цикла по каждому элементу Размещенный обмен - PullRequest
2 голосов
/ 21 июня 2011

У меня есть CSV из адресов электронной почты и отделов, которые мне нужно установить на Live @ edu. Команда, которая у меня сейчас есть, выглядит примерно так:

Import-CSV departments.csv | ForEach-Object { Set-User $_.EmailAddress $_.Department }`

Проблема в том, что эта операция занимает ВСЕ.

Сначала я подумал, что было бы здорово, чтобы команда ForEach-Object была действительно перенаправлена ​​на удаленную машину, так что ей нужно будет создать только один конвейер между двумя машинами, но когда я перейду к PSSession, кажется, что foreach-object не доступно. Для справки, как я импортирую сеанс PSSession:

Import-PSSession(New-PSSession -ConfigurationName Microsoft.Exchange `
    -ConnectionUri 'https://ps.outlook.com/powershell' `
    -Credential (Get-Credential) `
    -Authentication Basic -AllowRedirection)

Есть ли лучший способ импортировать сеанс, чтобы позволить ForEach-Object быть удаленным, или импортировать псевдоним удаленного foreach-объекта, возможно, как ForEach-Object-Remote, или, возможно, у кого-то есть что-то лучше предложить упростить этот процесс?

UPDATE: Пара вещей, которые я пробовал:

  1. Использование переключателя -AsJob для неявно удаленной команды.

    Import-CSV departments.csv | ForEach-Object { Set-User $_.EmailAddress $_.Department -AsJob }
    

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

  2. Импорт ForEach-Object под другим именем.

    Оказывается, что добавить префикс просто, как ввести -Prefix RS в команду Import-PSSession, чтобы такие вещи, как ForEach-Object из удаленного сеанса, стали ForEach-RSObject в локальном сеансе. К сожалению, это не будет работать для меня, потому что сервер, к которому я подключаюсь, не имеет Microsoft.Powershell ConfigurationName, доступного мне.

ОБНОВЛЕНИЕ 2: похоже, что командлет Set-User предоставлен корпорацией Майкрософт для администрирования Live @ edu. Его цель - установить атрибуты пользователя. Это не скрипт или командлет, которые я могу отлаживать. К сожалению, он не требует конвейерного ввода, так что это не сможет решить проблему.

Насколько я могу судить, проблема в том, что он должен создавать и выводить конвейер на удаленную машину при каждом запуске этой команды, а не использовать ее повторно. Идея удаленного ForEach позволила бы мне разгрузить этот цикл, чтобы избежать необходимости создавать все эти удаленные конвейеры, в то время как -asJob позволил бы им всем работать параллельно. Тем не менее, это также приводило к ошибкам, приводящим к сбою, и только некоторые записи действительно обновлялись должным образом.

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

РЕДАКТИРОВАТЬ: Start-Automate оставил очень полезную помощь, к сожалению, ни один из них не работает. На данный момент я чувствую, что не смогу ускорить это, пока мой провайдер не предоставит доступ к большему количеству командлетов powershell или пока не будут изменены командлеты exchange, чтобы разрешить несколько конвейеров, чего я не ожидаю в ближайшее время , Я отмечаю его ответ как правильный, несмотря на конечный результат, который ничем существенно не помогает. Спасибо, Пуск-Автоматизация .

1 Ответ

1 голос
/ 22 июня 2011

Вы можете ускорить ваш сценарий, а также не пытаться установить два подключения к серверу с помощью оператора foreach вместо Foreach-Object.

$departments = @(import-csv .\departments.csv)

foreach ($user in $departments) {
    Set-User $user.EmailAddress $user.Department 
} 

Если вам нужно выполнить пакет, вы можете использовать оператор for, двигаясь вперед в каждом пакете

for ($i =0; $i -lt $departments.Count; $i+=3) {
     $jobs = @()
     $jobs+= Invoke-Command { Set-User $departments[$i].EmailAddress $departments[$i].Department } -AsJob
     $jobs+= Invoke-Command { Set-User $departments[$i + 1].EmailAddress $departments[$i + 1].Department } -AsJob
     $jobs+= Invoke-Command { Set-User $departments[$i + 2].EmailAddress $departments[$i + 2].Department } -AsJob
     $jobs | Wait-job | Receive-job
}

Надеюсь, это поможет

...