在 PowerShell 脚本中调用其他 PowerShell 脚本

Jus*_*rce 6 powershell

我正在尝试让一个主 PowerShell 脚本运行所有其他脚本,同时等待 30-60 秒以确保完成任务。我尝试过的所有其他操作都不会停止/等待第一个脚本及其进程完成,然后才能同时完成所有其他脚本,并且会导致自动重新启动。

主脚本,以管理员身份运行:

$LogStart = 'Log '

$LogDate = Get-Date -Format "dd-MM-yyy-hh-mm-ss"

$FileName = $LogStart + $LogDate + '.txt.'

$scriptList = @(
    'C:\Scripts\1-OneDriveUninstall.ps1'
    'C:\Scripts\2-ComputerRename.ps1'
);

Start-Transcript -Path "C:\Scripts\$FileName"

foreach ($script in $scriptList) {
    Start-Process -FilePath "$PSHOME\powershell.exe" -ArgumentList "-Command '& $script'" 
    Write-Output "The $script is running."
    Start-Sleep -Seconds 30
}

Write-Output "Scripts have completed. Computer will restart in 10 seconds."
Start-Sleep -Seconds 10

Stop-Transcript

C:\Scripts\3-Restart.ps1
Run Code Online (Sandbox Code Playgroud)

1-OneDriveUninstall.ps1

Set-ItemProperty -Path REGISTRY::HKEY_LOCAL_MACHINE\Software\Microsoft\windows\CurrentVersion\Policies\System -Name ConsentPromptBehaviorAdmin -Value 0

taskkill /f /im OneDrive.exe

C:\Windows\SysWOW64\OneDriveSetup.exe /uninstall
Run Code Online (Sandbox Code Playgroud)

2-ComputerRename.ps1

$computername = Get-Content env:computername
$servicetag = Get-WmiObject Win32_Bios |
              Select-Object -ExpandProperty SerialNumber
if ($computername -ne $servicetag) {
    Write-Host "Renaming computer to $servicetag..."
    Rename-Computer -NewName $servicetag
} else {
    Write-Host "Computer name is already set to service tag."
}
Run Code Online (Sandbox Code Playgroud)

日志文件显示:

转录开始,输出文件为 C:\Scripts\Log 13-09-2019-04-28-47.txt。
C:\Scripts\1-OneDriveUninstall.ps1 正在运行。
C:\Scripts\2-ComputerRename.ps1 正在运行。
脚本已经完成。计算机将在 10 秒后重新启动。
Windows PowerShell 成绩单结束
结束时间:20190913162957

但是,它们根本没有正确运行。它们单独运行良好,但放入一个主脚本时则不能。

Ans*_*ers 10

PowerShell 可以直接从其他 PowerShell 脚本运行 PowerShell 脚本。您唯一需要这样做的时候Start-Process是当您想以提升的权限运行被调用的脚本时(这里不需要,因为您的父脚本已经提升了运行权限)。

这应该足够了:

foreach ($script in $scriptList) {
    & $script 
}
Run Code Online (Sandbox Code Playgroud)

上面的代码将按顺序运行脚本(即只有在前一个脚本终止后才启动下一个脚本)。如果要并行运行脚本,规范的方法是使用后台作业

$jobs = foreach ($script in $scriptList) {
    Start-Job -ScriptBlock { & $using:script }
}
$jobs | Wait-Job | Receive-Job
Run Code Online (Sandbox Code Playgroud)