Adobe flash player powershell 远程安装问题

Adobe flash player powershell remote install problem

我正在尝试使用 PowerShell 开发脚本以远程 install/update 多台机器的 Flash 播放器。无论我做什么,我都无法让安装正常工作。我的工具非常有限,所以我必须使用 PowerShell 和 Flashplayer 的 MSI 安装。我将在下面 post 我的脚本,我们将不胜感激任何帮助。

$Computers = Get-Content C:\Users\name\Desktop\flash.txt

(tried these 3 methods to install none work)
$install = @("/a","/i", "\$Computer\c$\temp\flash\install_flash_player_32_plugin.msi", "/qn","/norestart")



Invoke-Command -ComputerName $Computer -ScriptBlock {Start-Process "Msiexec" -arg "$using:install" -Wait -PassThru} -Filepath msiexec.exe

    #This returns with "invoke-command: parameter set cannot be resolved using the specified named parameters"

Invoke-Command -ComputerName $computer -ScriptBlock {Start-Process -Filepath msiexec.exe "$using:install" -Wait -PassThru} -Filepath msiexec.exe

    #this returns the same error.

Invoke-Command -ComputerName $Computer -ScriptBlock {start-process msiexec -argumentlist @('/a','/i','"\$Computer\c$\temp\flash\install_flash_player_32_plugin.msi"','/qn')}

    #this seemingly skips the install entirely. 

我已经为其他程序使用了类似的脚本并且安装它们没有问题,但是 none 我使用或研究过的方法工作正常。

这应该可以解决问题,我将在下面解释为什么它不起作用:

$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 
}

所以,它没有工作,因为 Invoke-Command 上的 ScriptBlock 看不到您在 powershell 会话中声明的变量,把它想象成您正走到那台远程计算机并手动输入该代码,你不会有价值(比喻)。

我又做了一些改动:

  1. 我将所有参数移动到 1 个字符串中,不需要将它们放在数组中。
  2. 添加了 $Computers | 以遍历计算机名称。
  3. 删除了文件路径,因为它的用途不同,documentation(示例 #1)。
  4. $MinutesToWait 设置为您想要的任何分钟数。
  5. 不需要尝试通过msiexec,因为它自带windows默认路径是"C:\WINDOWS\system32\msiexec.exe"
  6. 添加了一个 return,尽管它从来都不是必需的,但为了使其更具可读性并向您展示 return msiexec 进程输出的意图。
  7. \$Computer\c$ 替换为 C:\,因为如果您指向主机,则无需使用网络连接,您是 运行 /
  8. 中的命令

希望对你有帮助,祝你好运。

编辑:

所以,正如你提到的管道执行卡住,我过去在为我的部门创建计算机准备脚本时遇到过这个问题,我所做的是使用作业创建安装的并行执行,所以如果有由于某种原因速度较慢或完全卡住并且永无止境的计算机您可以识别它,请按原样尝试以下操作以查看其工作原理然后进行替换:

#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 个仅等待的作业和 return 它的名称,然后在您设置的时间内完成的作业被认为是正确的,而没有被视为待处理的作业,两组都导出到 CSV 文件以供审查。您需要替换以下内容才能按预期工作:

  1. 在设置区域添加$params = '/i <path to AcroPro.msi> LANG_LIST=en_US TRANSFORMS="1033.mst" /qb'
  2. $computers的声明替换为$computers = Get-Content C:\Users\name\Desktop\flash.txt
  3. 用此答案中第一段代码中的 Invoke-command 替换 Start-Job 脚本块的主体。

你应该得到这样的结果:

.
.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
.

我知道它看起来一团糟,但它确实有效。 希望对你有帮助。