From a157386151527896d9ce1aae19709dc0673ea5b1 Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Tue, 16 Aug 2022 10:35:46 -0700 Subject: [PATCH 01/15] Make Register MU timeout --- .../RegisterMicrosoftUpdate.ps1 | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/PowerShell.Core.Instrumentation/RegisterMicrosoftUpdate.ps1 diff --git a/src/PowerShell.Core.Instrumentation/RegisterMicrosoftUpdate.ps1 b/src/PowerShell.Core.Instrumentation/RegisterMicrosoftUpdate.ps1 new file mode 100644 index 00000000000..f14d5752d91 --- /dev/null +++ b/src/PowerShell.Core.Instrumentation/RegisterMicrosoftUpdate.ps1 @@ -0,0 +1,23 @@ +# Set a 5 minute timeout +$timeOut = (Get-Date).AddSeconds(300) +# create a file path to get the result +$output = Join-Path -Path ([System.IO.Path]::GetTempPath()) -ChildPath "RegisterMuOutput.txt" +# start the process to register MU and write the result to +$process = Start-Process -PassThru -FilePath pwsh.exe -NoNewWindow -ArgumentList '-NoProfile', '-ExecutionPolicy', 'Bypass', '-Command', "`$null = (New-Object -ComObject Microsoft.Update.ServiceManager).AddService2('7971f918-a847-4430-9279-4a52d1efe18d', 7, '').IsPendingRegistrationWithAu > $output" +$result = $false +$null = [bool]::TryParse((Get-Content $output),[ref]$result) +while (!$process.HasExited -and $timeOut -gt (Get-Date)) { + Write-Verbose -Verbose "$($timeout.Subtract((Get-Date)).TotalMinutes) minutes left" + Start-Sleep -Seconds 5 +} +if (! $process.HasExited) { + Write-Verbose -Verbose "scripted timedout, exiting with code 258" + #exit 258 +} elseif (!$result) { + Write-Verbose -Verbose "scripted failed" + #exit 1 +} else { + Write-Verbose -Verbose "scripted passed" + #exit 0 +} + From e772c3699690430db2df141d0457e1518895e9a8 Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Tue, 16 Aug 2022 10:37:55 -0700 Subject: [PATCH 02/15] Update Product.wxs --- assets/wix/Product.wxs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/wix/Product.wxs b/assets/wix/Product.wxs index bf6ab5d7cd8..85cc0011d36 100644 --- a/assets/wix/Product.wxs +++ b/assets/wix/Product.wxs @@ -87,7 +87,7 @@ + Value=""[VersionFolder]pwsh.exe" -NoProfile -ExecutionPolicy Bypass -File "[VersionFolder]RegisterMicrosoftUpdate.ps1"" /> Date: Tue, 16 Aug 2022 10:39:13 -0700 Subject: [PATCH 03/15] Update powershell-win-core.csproj --- src/powershell-win-core/powershell-win-core.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/powershell-win-core/powershell-win-core.csproj b/src/powershell-win-core/powershell-win-core.csproj index 16f625827d4..a10429c48ec 100644 --- a/src/powershell-win-core/powershell-win-core.csproj +++ b/src/powershell-win-core/powershell-win-core.csproj @@ -29,7 +29,7 @@ PreserveNewest PreserveNewest - + PreserveNewest PreserveNewest From 33bf51a1d63fb1e12a33b31693cfb2968007761c Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Tue, 16 Aug 2022 10:41:11 -0700 Subject: [PATCH 04/15] Rename src/PowerShell.Core.Instrumentation/RegisterMicrosoftUpdate.ps1 to assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 --- .../MicrosoftUpdate}/RegisterMicrosoftUpdate.ps1 | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {src/PowerShell.Core.Instrumentation => assets/MicrosoftUpdate}/RegisterMicrosoftUpdate.ps1 (100%) diff --git a/src/PowerShell.Core.Instrumentation/RegisterMicrosoftUpdate.ps1 b/assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 similarity index 100% rename from src/PowerShell.Core.Instrumentation/RegisterMicrosoftUpdate.ps1 rename to assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 From 90d88c6e5e311170bd90c9ce4b355b7f61738f5a Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Tue, 16 Aug 2022 10:42:54 -0700 Subject: [PATCH 05/15] Update src/powershell-win-core/powershell-win-core.csproj --- src/powershell-win-core/powershell-win-core.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/powershell-win-core/powershell-win-core.csproj b/src/powershell-win-core/powershell-win-core.csproj index a10429c48ec..9879e8485b4 100644 --- a/src/powershell-win-core/powershell-win-core.csproj +++ b/src/powershell-win-core/powershell-win-core.csproj @@ -29,7 +29,7 @@ PreserveNewest PreserveNewest - + PreserveNewest PreserveNewest From 1915f3e6b2ea114676aedf576290f2ca66d215da Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Tue, 16 Aug 2022 10:48:13 -0700 Subject: [PATCH 06/15] Update RegisterMicrosoftUpdate.ps1 --- assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 b/assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 index f14d5752d91..1c12dc292be 100644 --- a/assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 +++ b/assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + # Set a 5 minute timeout $timeOut = (Get-Date).AddSeconds(300) # create a file path to get the result From ff1552781503f91b257dda51dd577458de40ac44 Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Tue, 16 Aug 2022 10:49:39 -0700 Subject: [PATCH 07/15] Update RegisterMicrosoftUpdate.ps1 --- assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 b/assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 index 1c12dc292be..11b68c87c43 100644 --- a/assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 +++ b/assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 @@ -9,18 +9,22 @@ $output = Join-Path -Path ([System.IO.Path]::GetTempPath()) -ChildPath "Register $process = Start-Process -PassThru -FilePath pwsh.exe -NoNewWindow -ArgumentList '-NoProfile', '-ExecutionPolicy', 'Bypass', '-Command', "`$null = (New-Object -ComObject Microsoft.Update.ServiceManager).AddService2('7971f918-a847-4430-9279-4a52d1efe18d', 7, '').IsPendingRegistrationWithAu > $output" $result = $false $null = [bool]::TryParse((Get-Content $output),[ref]$result) + +# Wait for the process to exit or the timeout to pass while (!$process.HasExited -and $timeOut -gt (Get-Date)) { Write-Verbose -Verbose "$($timeout.Subtract((Get-Date)).TotalMinutes) minutes left" Start-Sleep -Seconds 5 } + +# If the process hasn't exited, exit with the timeout exit code if (! $process.HasExited) { Write-Verbose -Verbose "scripted timedout, exiting with code 258" - #exit 258 + exit 258 } elseif (!$result) { Write-Verbose -Verbose "scripted failed" - #exit 1 + exit 1 } else { Write-Verbose -Verbose "scripted passed" - #exit 0 + exit 0 } From 65d8114a7887f1888b9cf85fd556b5a928f90e1d Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Tue, 16 Aug 2022 10:58:59 -0700 Subject: [PATCH 08/15] Update files.wxs --- assets/wix/files.wxs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/assets/wix/files.wxs b/assets/wix/files.wxs index 6f7d0e6cbc5..4da5773c5e4 100644 --- a/assets/wix/files.wxs +++ b/assets/wix/files.wxs @@ -3150,6 +3150,9 @@ + + + @@ -4162,6 +4165,7 @@ + From 307bd1c568199b69fc29acdfba41a695bf0d1dbf Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Wed, 17 Aug 2022 12:27:52 -0700 Subject: [PATCH 09/15] Update assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 Co-authored-by: Aditya Patwardhan --- assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 b/assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 index 11b68c87c43..c268af26b55 100644 --- a/assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 +++ b/assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 @@ -21,7 +21,7 @@ if (! $process.HasExited) { Write-Verbose -Verbose "scripted timedout, exiting with code 258" exit 258 } elseif (!$result) { - Write-Verbose -Verbose "scripted failed" + Write-Verbose -Verbose "script failed" exit 1 } else { Write-Verbose -Verbose "scripted passed" From 7f82597d70b5d1fa68a25393aa277cd9d5871d82 Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Wed, 17 Aug 2022 12:27:58 -0700 Subject: [PATCH 10/15] Update assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 Co-authored-by: Aditya Patwardhan --- assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 b/assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 index c268af26b55..00b70665edf 100644 --- a/assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 +++ b/assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 @@ -24,7 +24,7 @@ if (! $process.HasExited) { Write-Verbose -Verbose "script failed" exit 1 } else { - Write-Verbose -Verbose "scripted passed" + Write-Verbose -Verbose "script passed" exit 0 } From 181cc3526aa3779faff4c2e6b257cce5fdd18e5c Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Wed, 17 Aug 2022 13:22:37 -0700 Subject: [PATCH 11/15] Update RegisterMicrosoftUpdate.ps1 --- .../RegisterMicrosoftUpdate.ps1 | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 b/assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 index 00b70665edf..232395744e8 100644 --- a/assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 +++ b/assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 @@ -5,10 +5,16 @@ $timeOut = (Get-Date).AddSeconds(300) # create a file path to get the result $output = Join-Path -Path ([System.IO.Path]::GetTempPath()) -ChildPath "RegisterMuOutput.txt" -# start the process to register MU and write the result to +# start the process to register MU and write the result to $process = Start-Process -PassThru -FilePath pwsh.exe -NoNewWindow -ArgumentList '-NoProfile', '-ExecutionPolicy', 'Bypass', '-Command', "`$null = (New-Object -ComObject Microsoft.Update.ServiceManager).AddService2('7971f918-a847-4430-9279-4a52d1efe18d', 7, '').IsPendingRegistrationWithAu > $output" -$result = $false -$null = [bool]::TryParse((Get-Content $output),[ref]$result) +function Get-IsFailed { + $result = $true + # Output is false or null if it fails + $outputText = Get-Content $output + Write-Verbose -Verbose "output: $outputText" + $null = [bool]::TryParse($outputText, [ref]$result) + return $result +} # Wait for the process to exit or the timeout to pass while (!$process.HasExited -and $timeOut -gt (Get-Date)) { @@ -20,11 +26,12 @@ while (!$process.HasExited -and $timeOut -gt (Get-Date)) { if (! $process.HasExited) { Write-Verbose -Verbose "scripted timedout, exiting with code 258" exit 258 -} elseif (!$result) { +} +elseif (Get-IsFailed) { Write-Verbose -Verbose "script failed" exit 1 -} else { +} +else { Write-Verbose -Verbose "script passed" exit 0 } - From df1903491d4a56d06b06e7d414adec6e744bf43b Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Wed, 17 Aug 2022 13:23:51 -0700 Subject: [PATCH 12/15] Update RegisterMicrosoftUpdate.ps1 --- assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 b/assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 index 232395744e8..afa36e81438 100644 --- a/assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 +++ b/assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 @@ -5,7 +5,7 @@ $timeOut = (Get-Date).AddSeconds(300) # create a file path to get the result $output = Join-Path -Path ([System.IO.Path]::GetTempPath()) -ChildPath "RegisterMuOutput.txt" -# start the process to register MU and write the result to +# start the process to register MU and write the result to a temporary file $process = Start-Process -PassThru -FilePath pwsh.exe -NoNewWindow -ArgumentList '-NoProfile', '-ExecutionPolicy', 'Bypass', '-Command', "`$null = (New-Object -ComObject Microsoft.Update.ServiceManager).AddService2('7971f918-a847-4430-9279-4a52d1efe18d', 7, '').IsPendingRegistrationWithAu > $output" function Get-IsFailed { $result = $true From 21aa4c2db56eb59518bb98aaf000a80ab306669e Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Wed, 17 Aug 2022 15:20:01 -0700 Subject: [PATCH 13/15] Update RegisterMicrosoftUpdate.ps1 --- .../RegisterMicrosoftUpdate.ps1 | 87 +++++++++++++------ 1 file changed, 59 insertions(+), 28 deletions(-) diff --git a/assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 b/assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 index afa36e81438..f3776a4775d 100644 --- a/assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 +++ b/assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 @@ -1,37 +1,68 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. -# Set a 5 minute timeout -$timeOut = (Get-Date).AddSeconds(300) -# create a file path to get the result -$output = Join-Path -Path ([System.IO.Path]::GetTempPath()) -ChildPath "RegisterMuOutput.txt" -# start the process to register MU and write the result to a temporary file -$process = Start-Process -PassThru -FilePath pwsh.exe -NoNewWindow -ArgumentList '-NoProfile', '-ExecutionPolicy', 'Bypass', '-Command', "`$null = (New-Object -ComObject Microsoft.Update.ServiceManager).AddService2('7971f918-a847-4430-9279-4a52d1efe18d', 7, '').IsPendingRegistrationWithAu > $output" -function Get-IsFailed { - $result = $true - # Output is false or null if it fails - $outputText = Get-Content $output - Write-Verbose -Verbose "output: $outputText" - $null = [bool]::TryParse($outputText, [ref]$result) - return $result -} +param( + [ValidateSet('Registration', 'Sleep', 'Fail')] + $Scenario = 'Registration' +) -# Wait for the process to exit or the timeout to pass -while (!$process.HasExited -and $timeOut -gt (Get-Date)) { - Write-Verbose -Verbose "$($timeout.Subtract((Get-Date)).TotalMinutes) minutes left" - Start-Sleep -Seconds 5 -} +$sleep = 300 +switch ($Scenario) { + 'Sleep' { + $sleep = 10 + $jobScript = { Start-Sleep -Seconds 600 } + } + 'Fail' { + $jobScript = { throw "This job script should fail" } + } + default { + $jobScript = { + # This registers Microsoft Update via a predifened GUID with the Windows Update Agent. + # https://docs.microsoft.com/en-us/windows/win32/wua_sdk/opt-in-to-microsoft-update -# If the process hasn't exited, exit with the timeout exit code -if (! $process.HasExited) { - Write-Verbose -Verbose "scripted timedout, exiting with code 258" - exit 258 + $serviceManager = (New-Object -ComObject Microsoft.Update.ServiceManager) + $isRegistered = $serviceManager.QueryServiceRegistration('7971f918-a847-4430-9279-4a52d1efe18d').Service.IsRegisteredWithAu + + if (!$isRegistered) { + Write-Verbose -Verbose "Opting into Microsoft Update as the Autmatic Update Service" + # 7 is the combination of asfAllowPendingRegistration, asfAllowOnlineRegistration, asfRegisterServiceWithAU + # AU means Automatic Updates + $null = $serviceManager.AddService2('7971f918-a847-4430-9279-4a52d1efe18d', 7, '').IsPendingRegistrationWithAu + } + else { + Write-Verbose -Verbose "Microsoft Update is already registered for Automatic Updates" + } + + $isRegistered = $serviceManager.QueryServiceRegistration('7971f918-a847-4430-9279-4a52d1efe18d').Service.IsRegisteredWithAu + + # Return if it was successful, which is the opposite of Pending. + return $isRegistered + } + } } -elseif (Get-IsFailed) { - Write-Verbose -Verbose "script failed" - exit 1 + +Write-Verbose "Running job script: $jobScript" -Verbose +$job = Start-ThreadJob -ScriptBlock $jobScript + +Write-Verbose "Waiting on Job for $sleep seconds" -Verbose +$null = Wait-Job -Job $job -Timeout $sleep + +if ($job.State -ne 'Running') { + Write-Verbose "Job finished. State: $($job.State)" -Verbose + $result = Receive-Job -Job $job -Verbose + Write-Verbose "Result: $result" -Verbose + if ($result) { + Write-Verbose "Registration succeeded" -Verbose + exit 0 + } + else { + Write-Verbose "Registration failed" -Verbose + exit 1 + } } else { - Write-Verbose -Verbose "script passed" - exit 0 + Write-Verbose "Job timed out" -Verbose + Write-Verbose "Stopping Job. State: $($job.State)" -Verbose + Stop-Job -Job $job + exit 258 } From 38377bad7ea6868849d1f7b896e7bc7f43f891ff Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Wed, 17 Aug 2022 15:39:08 -0700 Subject: [PATCH 14/15] Update RegisterMicrosoftUpdate.ps1 --- .../RegisterMicrosoftUpdate.ps1 | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 b/assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 index f3776a4775d..22077904b01 100644 --- a/assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 +++ b/assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 @@ -2,14 +2,14 @@ # Licensed under the MIT License. param( - [ValidateSet('Registration', 'Sleep', 'Fail')] - $Scenario = 'Registration' + [ValidateSet('Hang', 'Fail')] + $TestHook ) -$sleep = 300 -switch ($Scenario) { - 'Sleep' { - $sleep = 10 +$waitTimeoutSeconds = 300 +switch ($TestHook) { + 'Hang' { + $waitTimeoutSeconds = 10 $jobScript = { Start-Sleep -Seconds 600 } } 'Fail' { @@ -44,8 +44,8 @@ switch ($Scenario) { Write-Verbose "Running job script: $jobScript" -Verbose $job = Start-ThreadJob -ScriptBlock $jobScript -Write-Verbose "Waiting on Job for $sleep seconds" -Verbose -$null = Wait-Job -Job $job -Timeout $sleep +Write-Verbose "Waiting on Job for $waitTimeoutSeconds seconds" -Verbose +$null = Wait-Job -Job $job -Timeout $waitTimeoutSeconds if ($job.State -ne 'Running') { Write-Verbose "Job finished. State: $($job.State)" -Verbose @@ -57,6 +57,7 @@ if ($job.State -ne 'Running') { } else { Write-Verbose "Registration failed" -Verbose + # at the time this was written, the MSI is ignoring the exit code exit 1 } } @@ -64,5 +65,6 @@ else { Write-Verbose "Job timed out" -Verbose Write-Verbose "Stopping Job. State: $($job.State)" -Verbose Stop-Job -Job $job + # at the time this was written, the MSI is ignoring the exit code exit 258 } From b2622689c74a623f92d14e79f7b234da8a58ad97 Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Wed, 17 Aug 2022 15:39:20 -0700 Subject: [PATCH 15/15] Update assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 --- assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 b/assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 index 22077904b01..fd341d4fbef 100644 --- a/assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 +++ b/assets/MicrosoftUpdate/RegisterMicrosoftUpdate.ps1 @@ -27,7 +27,7 @@ switch ($TestHook) { Write-Verbose -Verbose "Opting into Microsoft Update as the Autmatic Update Service" # 7 is the combination of asfAllowPendingRegistration, asfAllowOnlineRegistration, asfRegisterServiceWithAU # AU means Automatic Updates - $null = $serviceManager.AddService2('7971f918-a847-4430-9279-4a52d1efe18d', 7, '').IsPendingRegistrationWithAu + $null = $serviceManager.AddService2('7971f918-a847-4430-9279-4a52d1efe18d', 7, '') } else { Write-Verbose -Verbose "Microsoft Update is already registered for Automatic Updates"