diff --git a/msoffice-removal-tool.ps1 b/msoffice-removal-tool.ps1 index fe3953f..f127604 100644 --- a/msoffice-removal-tool.ps1 +++ b/msoffice-removal-tool.ps1 @@ -1,5 +1,5 @@ #requires -version 2 -#Requires -RunAsAdministrator +#//Requires -RunAsAdministrator <# .SYNOPSIS @@ -15,6 +15,10 @@ Will use the setup method to remove current Office installations instead of SaRA. .PARAMETER Force Skip user-input. +.PARAMETER RunAgain + Skip Stage validation and runs the whole script again. +.PARAMETER SecondsToReboot + Seconds before the computer will reboot. .INPUTS None .OUTPUTS @@ -33,9 +37,10 @@ Param ( [switch]$InstallOffice365 = $False, [switch]$SuppressReboot = $False, [switch]$UseSetupRemoval = $False, - [Switch]$Force = $False + [Switch]$Force = $False, + [switch]$RunAgain = $False, + [int]$SecondsToReboot = 60 ) - #----------------------------------------------------------[Declarations]---------------------------------------------------------- $SaRA_URL = "https://aka.ms/SaRA_CommandLineVersionFiles" $SaRA_ZIP = "$env:TEMP\SaRA.zip" @@ -45,7 +50,7 @@ $Office365Setup_URL = "https://github.com/Admonstrator/msoffice-removal-tool/raw #-----------------------------------------------------------[Functions]------------------------------------------------------------ Function Invoke-OfficeUninstall { if (-Not (Test-Path "$SaRA_DIR")) { - New-Item "$SaRA_DIR" -ItemType Directory + New-Item "$SaRA_DIR" -ItemType Directory | Out-Null } if ($UseSetupRemoval) { Write-Host "Invoking default setup method ..." @@ -108,21 +113,25 @@ Function Invoke-SaRA { switch ($SaRAProcess.ExitCode) { 0 { Write-Host "Uninstall successful!" + Set-CurrentStage 2 Break } 7 { Write-Host "No office installations found." + Set-CurrentStage 2 Break } 8 { Write-Error "Multiple office installations found. Program need to be run in GUI mode." + Set-CurrentStage 4 Exit 2 } 9 { Write-Error "Uninstall failed! Program need to be run in GUI mode." + Set-CurrentStage 4 Exit 3 } } @@ -138,44 +147,108 @@ Function Invoke-SetupOffice365($Office365ConfigFile) { switch ($OfficeSetup.ExitCode) { 0 { Write-Host "Install successful!" + Set-CurrentStage 3 Break } 1 { Write-Error "Install failed!" + Set-CurrentStage 3 Break } } } } -Function Invoke-Reboot { +Function Invoke-RebootInSeconds($Seconds) { if (-not $SuppressReboot) { - Start-Process -FilePath "$env:SystemRoot\system32\shutdown.exe" -ArgumentList "/r /c `"Reboot needed. System will reboot in 60 seconds.`" /t 60 /f /d p:4:1" + Start-Process -FilePath "$env:SystemRoot\system32\shutdown.exe" -ArgumentList "/r /c `"Reboot needed. System will reboot in $Seconds seconds.`" /t $Seconds /f /d p:4:1" } } -#-----------------------------------------------------------[Execution]------------------------------------------------------------ -Write-Host " ___ ___ ___ _____ _____ _____ " -Write-Host "|_ | | |_ | | __| __| |" -Write-Host " _| |_| | |_| |_ | __| __| | | |" -Write-Host "|_____|___|_____| |__| |__| |_|_|_|" -Write-Host "" -Write-Host "Microsoft Office Removal Tool" -Write-Host "by Aaron Viehl (101 Frankfurt)" -Write-Host "einsnulleins.de" -Write-Host "" +Function Set-CurrentStage($StageValue) { + if (-not (Test-Path "HKLM:\Software\OEM\101\M365\Install")) { + New-Item -Path "HKLM:\Software\OEM\101\M365\Install" -Force | Out-Null + } + New-ItemProperty -Path "HKLM:\Software\OEM\101\M365\Install" -Name "CurrentStage" -Value $StageValue -PropertyType String -Force | Out-Null +} + +Function Invoke-Intro { + Write-Host " ___ ___ ___ _____ _____ _____ " + Write-Host "|_ | | |_ | | __| __| |" + Write-Host " _| |_| | |_| |_ | __| __| | | |" + Write-Host "|_____|___|_____| |__| |__| |_|_|_|" + Write-Host "" + Write-Host "Microsoft Office Removal Tool" + Write-Host "by Aaron Viehl (101 Frankfurt)" + Write-Host "einsnulleins.de" + Write-Host "" +} + +#-----------------------------------------------------------[Execution]------------------------------------------------------------ +# Check if -Force is set if (-Not $Force) { do { $YesOrNo = Read-Host "Are you sure you want to remove Office from this PC? (y/n)" } while ("y", "n" -notcontains $YesOrNo) if ($YesOrNo -eq "n") { - exit 1 + exit 1 } } -Stop-OfficeProcess -Invoke-OfficeUninstall -Invoke-SetupOffice365 "$Office365Setup_URL/upgrade.xml" -Invoke-Reboot \ No newline at end of file +# Check if there is a stage to resume +if (-not ($RunAgain)) { + if (Test-Path "HKLM:\Software\OEM\101\M365\Install") { + $CurrentStageValue = (Get-ItemProperty "HKLM:\Software\OEM\101\M365\Install").CurrentStage + Switch ($CurrentStageValue) { + 1 { + Write-Host "Resuming Stage 1: Uninstalling Office ..." + Invoke-OfficeUninstall + Invoke-SetupOffice365 "$Office365Setup_URL/upgrade.xml" + Remove-SaRA + Invoke-RebootInSeconds $SecondsToReboot + } + + 2 { + Write-Host "Resuming Stage 2: Installing Office 365 ..." + Invoke-SetupOffice365 "$Office365Setup_URL/upgrade.xml" + Remove-SaRA + Invoke-RebootInSeconds $SecondsToReboot + } + + 3 { + Write-Host "Resuming Stage 3: Cleaning up ..." + Remove-SaRA + } + + 4 { + # Final stage: All is done, script will not run. + exit 0 + } + + default { + Write-Host "Resuming Stage 1: Uninstalling Office ..." + Invoke-OfficeUninstall + Invoke-SetupOffice365 "$Office365Setup_URL/upgrade.xml" + Remove-SaRA + Invoke-RebootInSeconds $SecondsToReboot + } + } + } + else { + Invoke-Intro + Stop-OfficeProcess + Invoke-OfficeUninstall + Invoke-SetupOffice365 "$Office365Setup_URL/upgrade.xml" + Invoke-RebootInSeconds $SecondsToReboot + } +} +else { + Invoke-Intro + Stop-OfficeProcess + Invoke-OfficeUninstall + Invoke-SetupOffice365 "$Office365Setup_URL/upgrade.xml" + Invoke-RebootInSeconds $SecondsToReboot +} +exit \ No newline at end of file diff --git a/readme.md b/readme.md index 16d9d61..22b85f9 100644 --- a/readme.md +++ b/readme.md @@ -23,13 +23,21 @@ By using `-UseSetupRemoval` the Office365 setup method will be used. ## Parameter -| Parameter | Usage | -|-------------------|-------------------------------------------------------------------------| -| -InstallOffice365 | The script will try to install the newest Office365 build after removal | -| -SuppressReboot | No reboot will be executed after script is done | -| -UseSetupRemoval | Will use the official Office365 setup instead of SaRA | -| -Force | Non-interactive - No user interaction required | +| Parameter | Usage | +|------------------------|-------------------------------------------------------------------------| +| -InstallOffice365 | The script will try to install the newest Office365 build after removal | +| -SuppressReboot | No reboot will be executed after script is done | +| -UseSetupRemoval | Will use the official Office365 setup instead of SaRA | +| -RunAgain | Will skip the stage mechanism - whole script will run again | +| -Force | Non-interactive - No user interaction required | +| -SecondsToReboot [int] | Seconds until the computer will reboot | ### Example ``.\msoffice-removal-tool.ps1 -InstallOffice365 -SuppressReboot -Force`` + +### Stage mechanism + +To make sure that the program will only do the necessary parts a _stage mechanism_ is builtin. After every stage a registry value will be written to ``HKLM:\Software\OEM\101\M365\Install\CurrentStage`` + +To overwrite all stages and restart the whole script use ``-RunAgain``