Это должно сработать, я объясню, почему это не сработало ниже:
$Computers = Get-Content C:\Users\name\Desktop\flash.txt
$params = '/i <path to AcroPro.msi> LANG_LIST=en_US TRANSFORMS="1033.mst" /qb'
$Computers | % {
Invoke-Command -ScriptBlock {
Param(
[Parameter(Mandatory=$true,Position=0)]
[String]$arguments
)
return Start-Process msiexec.exe -ArgumentList $arguments -Wait -PassThru
} -ComputerName $_ -ArgumentList $params
}
Итак, это не сработало, потому что ScriptBlock на Invoke-Command не может видеть переменные, которые вы ' Если вы объявили о своем сеансе PowerShell, подумайте, что вы идете на этот удаленный компьютер и вводите этот код вручную, у вас не будет значения (метафоры).
Я сделал еще несколько изменений:
- Я переместил все параметры в одну строку, нет необходимости иметь их в массиве.
- Добавлен
$Computers |
в перебирайте имена компьютеров. - Удален FilePath, так как он предназначен для другого использования, документация (Пример # 1).
- Установите для
$MinutesToWait
любое количество минут вы хотите. - Не нужно пытаться передать msiexe c, так как он идет с windows по умолчанию путь "C: \ WINDOWS \ system32 \ msiexe c .exe"
- Добавлен возврат, хотя он никогда не нужен, но для того, чтобы сделать его более читабельным и показать намерение вернуть выходные данные процесса msiexe c.
- Заменен
\\$Computer\c$
на C:\
поскольку нет необходимости использовать сетевое соединение, если вы указываете на хост, на котором вы запускаете команду в /
Надеюсь, это поможет, удачи.
РЕДАКТИРОВАТЬ:
Итак, как вы упомянули, конвейерный процесс зависает, у меня была эта проблема в прошлом при создании компьютера. Сценарий ремонта для моего отдела. Я использовал задания для параллельного выполнения установки, поэтому, если есть компьютер, который по какой-то причине работает медленнее или просто зависает и никогда не останавливается, вы можете его идентифицировать, попробуйте выполнить следующие действия, чтобы посмотрите, как это работает, а затем выполните замены:
#region ######## SetUp #######
$bannerInProgress = @"
#######################
#Jobs are still running
#######################
"@
$bannerDone = @"
##################################################
#DONE see results of finished installations bellow
##################################################
"@
#VARS TO SET
$MinutesToWait = 1
$computers = 1..10 | % {"qwerty"*$_} #REPLACE THIS WITH YOUR COMPUTER VALUES (Get-Content C:\Users\name\Desktop\flash.txt)
#endregion
#region ######## Main #######
#Start Jobs (REPLACE SCRIPTBLOCK OF JOB WITH YOUR INVOKE-COMMAND)
$jobs = [System.Collections.ArrayList]::new()
foreach($computer in $computers){
$jobs.Add(
(Start-Job -Name $computer -ScriptBlock {
Param(
[Parameter(Mandatory=$true, Position=0)]
[String]$computer
)
Sleep -s (Get-Random -Minimum 5 -Maximum 200)
$computer
} -ArgumentList $computer)
) | Out-Null
}
$timer = [System.Diagnostics.Stopwatch]::new()
$timer.Start()
$acceptedWait = $MinutesToWait * 60 * 1000 # mins -> sec -> millis
$running = $true
do {
cls
$jobsRunning = $jobs | Where-Object State -EQ 'Running'
if ($jobsRunning) {
Write-Host $bannerInProgress
foreach ($job in $jobsRunning) {
Write-Host "The job `"$($job.Name)`" is still running. It started at $($job.PSBeginTime)"
}
Sleep -s 3
} else {
$running = $false
}
if($timer.ElapsedMilliseconds -ge $acceptedWait){
$timer.Stop()
Write-Host "Accepted time was reached, stopping all jobs still pending." -BackgroundColor Red
$failed = @()
foreach($job in $jobsRunning){
$output = $job | Receive-Job
$failed += [PsCustomObject]@{
"ComputerName" = $job.Name;
"Output" = $output;
}
$job | Remove-Job -Force
$jobs.Remove($job)
}
$failed | Export-Csv .\pendingInstallations.csv -NoTypeInformation -Force
$running = $false
}
}while($running)
Write-host $bannerDone
$results = @()
foreach($job in $jobs){
$output = $job | Receive-Job
$results += [PsCustomObject]@{
"ComputerName" = $job.Name;
"Output" = $output;
}
}
$results | Export-Csv .\install.csv -NoTypeInformation -Force
#endregion
Этот сценарий вызовет 10 заданий, которые только ждут и возвращают свои имена, затем задания, выполненные за заданное вами время, считаются правильными, и те, которые не считаются ожидающими рассмотрения, обе группы экспортируются в CSV для проверки. Вам нужно заменить следующее, чтобы работать так, как вы предполагали:
- Добавить
$params = '/i <path to AcroPro.msi> LANG_LIST=en_US TRANSFORMS="1033.mst" /qb'
в области настроек - Заменить объявление
$computers
на $computers = Get-Content C:\Users\name\Desktop\flash.txt
- Замените тело
Start-Job
скриптового блока на Invoke-command
из первого фрагмента кода в этом ответе.
Вы должны получить что-то вроде:
.
.code
.
$params = '/i <path to AcroPro.msi> LANG_LIST=en_US TRANSFORMS="1033.mst" /qb'
#VARS TO SET
$MinutesToWait = 1
$computers = Get-Content C:\Users\name\Desktop\flash.txt
#endregion
#region ######## Main #######
#Start Jobs
$jobs = [System.Collections.ArrayList]::new()
foreach($computer in $computers){
$jobs.Add(
(Start-Job -Name $computer -ScriptBlock {
Param(
[Parameter(Mandatory=$true, Position=0)]
[String]$computer
)
Invoke-Command -ScriptBlock {
Param(
[Parameter(Mandatory=$true,Position=0)]
[String]$arguments
)
return Start-Process msiexec.exe -ArgumentList $arguments -Wait -PassThru
} -ComputerName $computer -ArgumentList $params
} -ArgumentList $computer)
) | Out-Null
}
.
. code
.
Я знаю, это выглядит как полный беспорядок, но это работает. Надеюсь, это поможет.