Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling other PowerShell scripts within a PowerShell script

Tags:

powershell

I'm trying to get one master PowerShell script to run all of the others while waiting 30-60 seconds to ensure that the tasks are completed. Everything else I tried wouldn't stop/wait for the first script and its processes to complete before going through all the others at the same time and would cause a restart automatically.

Main script, run as admin:

$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

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

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

The log file shows:

Transcript started, output file is C:\Scripts\Log 13-09-2019-04-28-47.txt.
The C:\Scripts\1-OneDriveUninstall.ps1 is running.
The C:\Scripts\2-ComputerRename.ps1 is running.
Scripts have completed. Computer will restart in 10 seconds.
Windows PowerShell transcript end
End time: 20190913162957

They aren't running correctly at all though. They run fine individually but not when put into one master script.

like image 914
Justin Pierce Avatar asked Sep 14 '19 02:09

Justin Pierce


Video Answer


1 Answers

PowerShell can run PowerShell scripts from other PowerShell scripts directly. The only time you need Start-Process for that is when you want to run the called script with elevated privileges (which isn't necessary here, since your parent script is already running elevated).

This should suffice:

foreach ($script in $scriptList) {
    & $script 
}

The above code will run the scripts sequentially (i.e. start the next script only after the previous one terminated). If you want to run the scripts in parallel, the canonical way is to use background jobs:

$jobs = foreach ($script in $scriptList) {
    Start-Job -ScriptBlock { & $using:script }
}
$jobs | Wait-Job | Receive-Job
like image 177
Ansgar Wiechers Avatar answered Nov 04 '22 00:11

Ansgar Wiechers