This a bad commit message. NO idea.

This commit is contained in:
2022-02-15 14:56:51 -05:00
parent 4a8ab6fc84
commit 3fb974987c
62 changed files with 421 additions and 1063 deletions

View File

@@ -1,152 +0,0 @@
#Requires -Version 3.0
<#PSScriptInfo
.VERSION 1.0
.GUID 6cf319d1-8c50-460b-99ee-71b11cf7270d
.AUTHOR
Jordan Borean <jborean93@gmail.com>
.COPYRIGHT
Jordan Borean 2017
.TAGS
PowerShell,Ansible,WinRM,WMF,Hotfix
.LICENSEURI https://github.com/jborean93/ansible-windows/blob/master/LICENSE
.PROJECTURI https://github.com/jborean93/ansible-windows
.RELEASENOTES
Version 1.0: 2017-09-27
Initial script created
#>
<#
.DESCRIPTION
The script will install the WinRM hotfix KB2842230 which fixes the memory
issues that occur when running over WinRM with WMF 3.0.
The script will;
1. Detect if running on PS version 3.0 and exit if it is not
2. Check if KB2842230 is already installed and exit if it is
3. Download the hotfix from Microsoft server's based on the OS version
4. Extract the .msu file from the downloaded hotfix
5. Install the .msu silently
6. Detect if a reboot is required and prompt whether the user wants to restart
Once the install is complete, if the install process returns an exit
code of 3010, it will ask the user whether to restart the computer now
or whether it will be done later.
See https://github.com/jborean93/ansible-windows/tree/master/scripts for more
details.
.PARAMETER Verbose
[switch] - Whether to display Verbose logs on the console
.EXAMPLE
powershell.exe -ExecutionPolicy ByPass -File Install-WMF3Hotfix.ps1
.EXAMPLE
powershell.exe -ExecutionPolicy ByPass -File Install-WMF3Hotfix.ps1 -Verbose
#>
[CmdletBinding()]
Param()
$ErrorActionPreference = "Stop"
if ($verbose) {
$VerbosePreference = "Continue"
}
Function Run-Process($executable, $arguments) {
$process = New-Object -TypeName System.Diagnostics.Process
$psi = $process.StartInfo
$psi.FileName = $executable
$psi.Arguments = $arguments
Write-Verbose -Message "starting new process '$executable $arguments'"
$process.Start() | Out-Null
$process.WaitForExit() | Out-Null
$exit_code = $process.ExitCode
Write-Verbose -Message "process completed with exit code '$exit_code'"
return $exit_code
}
Function Download-File($url, $path) {
Write-Verbose -Message "downloading url '$url' to '$path'"
$client = New-Object -TypeName System.Net.WebClient
$client.DownloadFile($url, $path)
}
Function Extract-Zip($zip, $dest) {
Write-Verbose -Message "extracting '$zip' to '$dest'"
try {
Add-Type -AssemblyName System.IO.Compression.FileSystem > $null
$legacy = $false
} catch {
$legacy = $true
}
if ($legacy) {
$shell = New-Object -ComObject Shell.Application
$zip_src = $shell.NameSpace($zip)
$zip_dest = $shell.NameSpace($dest)
$zip_dest.CopyHere($zip_src.Items(), 1044)
} else {
[System.IO.Compression.ZipFile]::ExtractToDirectory($zip, $dest)
}
}
$tmp_dir = $env:temp
$kb = "KB2842230"
if ($PSVersionTable.PSVersion.Major -ne 3) {
Write-Verbose -Message "$kb is only applicable with Powershell v3, no action required"
exit 0
}
$hotfix_installed = Get-Hotfix -Id $kb -ErrorAction SilentlyContinue
if ($hotfix_installed -ne $null) {
Write-Verbose -Message "$kb is already installed"
exit 0
}
if (-not (Test-Path -Path $tmp_dir)) {
New-Item -Path $tmp_dir -ItemType Directory > $null
}
$os_version = [Version](Get-Item -Path "$env:SystemRoot\System32\kernel32.dll").VersionInfo.ProductVersion
$host_string = "$($os_version.Major).$($os_version.Minor)-$($env:PROCESSOR_ARCHITECTURE)"
switch($host_string) {
# These URLS point to the Ansible Core CI S3 bucket, MS no longer provide a link to Server 2008 so we need to
# rely on this URL. There are no guarantees this will stay up in the future.
"6.0-x86" {
$url = "https://s3.amazonaws.com/ansible-ci-files/hotfixes/KB2842230/464091_intl_i386_zip.exe"
}
"6.0-AMD64" {
$url = "https://s3.amazonaws.com/ansible-ci-files/hotfixes/KB2842230/464090_intl_x64_zip.exe"
}
"6.1-x86" {
$url = "https://s3.amazonaws.com/ansible-ci-files/hotfixes/KB2842230/463983_intl_i386_zip.exe"
}
"6.1-AMD64" {
$url = "https://s3.amazonaws.com/ansible-ci-files/hotfixes/KB2842230/463984_intl_x64_zip.exe"
}
"6.2-x86" {
$url = "https://s3.amazonaws.com/ansible-ci-files/hotfixes/KB2842230/463940_intl_i386_zip.exe"
}
"6.2-AMD64" {
$url = "https://s3.amazonaws.com/ansible-ci-files/hotfixes/KB2842230/463941_intl_x64_zip.exe"
}
}
$filename = $url.Split("/")[-1]
$compressed_file = "$tmp_dir\$($filename).zip"
Download-File -url $url -path $compressed_file
Extract-Zip -zip $compressed_file -dest $tmp_dir
$file = Get-Item -Path "$tmp_dir\*$kb*.msu"
if ($file -eq $null) {
Write-Error -Message "unable to find extracted msu file for hotfix KB"
exit 1
}
$exit_code = Run-Process -executable $file.FullName -arguments "/quiet /norestart"
if ($exit_code -eq 3010) {
Write-Verbose "need to restart computer after hotfix $kb install"
Restart-Computer -Force
} elseif ($exit_code -ne 0) {
Write-Error -Message "failed to install hotfix $($kb): exit code $exit_code"
} else {
Write-Verbose -Message "hotfix $kb install complete"
}
exit $exit_code

View File

@@ -1,400 +0,0 @@
# PSScriptInfo
# .VERSION 1.0
# .GUID 23743bae-7604-459d-82c5-a23d36b0820e
# .AUTHOR
# Jordan Borean <jborean93@gmail.com>
# .COPYRIGHT
# Jordan Borean 2017
# .TAGS
# PowerShell,Ansible
# .LICENSEURI https://github.com/jborean93/ansible-windows/blob/master/LICENSE
# .PROJECTURI https://github.com/jborean93/ansible-windows
# .RELEASENOTES
# Version 1.0: 2017-09-27
# Initial script created
# .DESCRIPTION
# The script will upgrade the powershell version to whatever is supplied as
# the 'version' on the host. The current versions can be set as the target
# 'version':
# - 3.0
# - 4.0
# - 5.1 (default if -Version not set)
#
# This script can be run on the following OS'
# Windows Server 2008 (with SP2) - only supported version 3.0
# Windows Server 2008 R2 (with SP1)
# Windows Server 2012
# Windows Server 2012 R2
# Windows Server 2016
#
# Windows 7 (with SP1)
# Windows 8.1
# Windows 10
#
# All OS' can be upgraded to 5.1 except for Windows Server 2008. If running
# on Powershell 1.0 then this script will first upgrade the version to 2.0
# before running the checks. This is because a lot of the upgrade paths need
# this version installed as a baseline. If the .NET Framework version
# installed is less than 4.5.2, it will be upgraded to 4.5.2 as this is
# supported on all hosts and is required for v5.0.
#
# As multiple packages can be installed in this process, multiple reboots may
# be required to continue with the install. If a reboot is required the
# script will detect if the 'username' and 'password' parameters have been
# supplied. If they have been supplied it will automatically reboot and login
# to continue the install process until it is all complete. If these
# parameters are not set then it will prompt the user for a reboot and
# require the user to log back in manually after the reboot before
# continuing.
#
# A log of this process is created in
# $env:SystemDrive\temp\upgrade_powershell.log which is usually C:\temp\. This
# log can used to see how the script faired after an automatic reboot.
#
# See https://github.com/jborean93/ansible-windows/tree/master/scripts for more
# details.
# .PARAMETER version
# [string] - The target powershell version to upgrade to. This can be;
# 3.0,
# 4.0, or
# 5.1 (default)
# Depending on the circumstances, the process to reach the target version
# may require multiple reboots.
# .PARAMETER username
# [string] - The username of a local admin user that will be automatically
# logged in after a reboot to continue the script install. The 'password'
# parameter is also required if this is set.
# .PARAMETER password
# [string] - The password for 'username', this is required if the 'username'
# parameter is also set.
# .PARAMETER Verbose
# [switch] - Whether to display Verbose logs on the console
# .EXAMPLE
# # upgrade from powershell 1.0 to 3.0 with automatic login and reboots
# Set-ExecutionPolicy Unrestricted -Force
# &.\Upgrade-PowerShell.ps1 -version 3.0 -username "Administrator" -password "Password" -Verbose
# .EXAMPLE
# # upgrade to 5.1 with defaults and manual login and reboots
# powershell.exe -ExecutionPolicy ByPass -File Upgrade-PowerShell.ps1
# .EXAMPLE
# # upgrade to powershell 4.0 with automatic login and reboots
# powershell.exe -ExecutionPolicy ByPass -File Upgrade-PowerShell.ps1 -version 4.0 -username "Administrator" -password "Password" -Verbose
Param(
[string]$version = "5.1",
[string]$username,
[string]$password,
[switch]$verbose = $false
)
$ErrorActionPreference = 'Stop'
if ($verbose) {
$VerbosePreference = "Continue"
}
$tmp_dir = $env:temp
if (-not (Test-Path -Path $tmp_dir)) {
New-Item -Path $tmp_dir -ItemType Directory > $null
}
Function Write-Log($message, $level="INFO") {
# Poor man's implementation of Log4Net
$date_stamp = Get-Date -Format s
$log_entry = "$date_stamp - $level - $message"
$log_file = "$tmp_dir\upgrade_powershell.log"
Write-Verbose -Message $log_entry
Add-Content -Path $log_file -Value $log_entry
}
Function Reboot-AndResume {
Write-Log -message "adding script to run on next logon"
$script_path = $script:MyInvocation.MyCommand.Path
$ps_path = "$env:SystemDrive\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"
$arguments = "-version $version"
if ($username -and $password) {
$arguments = "$arguments -username `"$username`" -password `"$password`""
}
if ($verbose) {
$arguments = "$arguments -Verbose"
}
$command = "$ps_path -ExecutionPolicy ByPass -File $script_path $arguments"
$reg_key = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce"
$reg_property_name = "ps-upgrade"
Set-ItemProperty -Path $reg_key -Name $reg_property_name -Value $command
if ($username -and $password) {
$reg_winlogon_path = "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Winlogon"
Set-ItemProperty -Path $reg_winlogon_path -Name AutoAdminLogon -Value 1
Set-ItemProperty -Path $reg_winlogon_path -Name DefaultUserName -Value $username
Set-ItemProperty -Path $reg_winlogon_path -Name DefaultPassword -Value $password
Write-Log -message "rebooting server to continue powershell upgrade"
} else {
Write-Log -message "need to reboot server to continue powershell upgrade"
$reboot_confirmation = Read-Host -Prompt "need to reboot server to continue powershell upgrade, do you wish to proceed (y/n)"
if ($reboot_confirmation -ne "y") {
$error_msg = "please reboot server manually and login to continue upgrade process, the script will restart on the next login automatically"
Write-Log -message $error_msg -level "ERROR"
throw $error_msg
}
}
if (Get-Command -Name Restart-Computer -ErrorAction SilentlyContinue) {
Restart-Computer -Force
} else {
# PS v1 (Server 2008) doesn't have the cmdlet Restart-Computer, use el-traditional
shutdown /r /t 0
}
}
Function Run-Process($executable, $arguments) {
$process = New-Object -TypeName System.Diagnostics.Process
$psi = $process.StartInfo
$psi.FileName = $executable
$psi.Arguments = $arguments
Write-Log -message "starting new process '$executable $arguments'"
$process.Start() | Out-Null
$process.WaitForExit() | Out-Null
$exit_code = $process.ExitCode
Write-Log -message "process completed with exit code '$exit_code'"
return $exit_code
}
Function Download-File($url, $path) {
Write-Log -message "downloading url '$url' to '$path'"
$client = New-Object -TypeName System.Net.WebClient
$client.DownloadFile($url, $path)
}
Function Clear-AutoLogon {
$reg_winlogon_path = "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Winlogon"
Write-Log -message "clearing auto logon registry properties"
Set-ItemProperty -Path $reg_winlogon_path -Name AutoAdminLogon -Value 0
Remove-ItemProperty -Path $reg_winlogon_path -Name DefaultUserName -ErrorAction SilentlyContinue
Remove-ItemProperty -Path $reg_winlogon_path -Name DefaultPassword -ErrorAction SilentlyContinue
}
Function Download-Wmf5Server2008($architecture) {
if ($architecture -eq "x64") {
$zip_url = "http://download.microsoft.com/download/6/F/5/6F5FF66C-6775-42B0-86C4-47D41F2DA187/Win7AndW2K8R2-KB3191566-x64.zip"
$file = "$tmp_dir\Win7AndW2K8R2-KB3191566-x64.msu"
} else {
$zip_url = "http://download.microsoft.com/download/6/F/5/6F5FF66C-6775-42B0-86C4-47D41F2DA187/Win7-KB3191566-x86.zip"
$file = "$tmp_dir\Win7-KB3191566-x86.msu"
}
if (Test-Path -Path $file) {
return $file
}
$filename = $zip_url.Split("/")[-1]
$zip_file = "$tmp_dir\$filename"
Download-File -url $zip_url -path $zip_file
Write-Log -message "extracting '$zip_file' to '$tmp_dir'"
try {
Add-Type -AssemblyName System.IO.Compression.FileSystem > $null
$legacy = $false
} catch {
$legacy = $true
}
if ($legacy) {
$shell = New-Object -ComObject Shell.Application
$zip_src = $shell.NameSpace($zip_file)
$zip_dest = $shell.NameSpace($tmp_dir)
$zip_dest.CopyHere($zip_src.Items(), 1044)
} else {
[System.IO.Compression.ZipFile]::ExtractToDirectory($zip_file, $tmp_dir)
}
return $file
}
Write-Log -message "starting script"
# on PS v1.0, upgrade to 2.0 and then run the script again
if ($PSVersionTable -eq $null) {
Write-Log -message "upgrading powershell v1.0 to v2.0"
$architecture = $env:PROCESSOR_ARCHITECTURE
if ($architecture -eq "AMD64") {
# this url not working
#$url = "https://download.microsoft.com/download/2/8/6/28686477-3242-4E96-9009-30B16BED89AF/Windows6.0-KB968930-x64.msu"
$url = "http://download.windowsupdate.com/msdownload/update/software/updt/2011/02/windows6.0-kb968930-x64_4de013d593181a2a04217ce3b0e7536ab56995aa.msu"
} else {
# this url not working
#$url = "https://download.microsoft.com/download/F/9/E/F9EF6ACB-2BA8-4845-9C10-85FC4A69B207/Windows6.0-KB968930-x86.msu"
$url = "http://download.windowsupdate.com/msdownload/update/software/updt/2011/02/windows6.0-kb968930-x86_16fd2e93be2e7265821191119ddfc0cdaa6f4243.msu"
}
$filename = $url.Split("/")[-1]
$file = "$tmp_dir\$filename"
Download-File -url $url -path $file
$exit_code = Run-Process -executable $file -arguments "/quiet /norestart"
if ($exit_code -ne 0 -and $exit_code -ne 3010) {
$error_msg = "failed to update Powershell from 1.0 to 2.0: exit code $exit_code"
Write-Log -message $error_msg -level "ERROR"
throw $error_msg
}
Reboot-AndResume
}
# exit if the target version is the same as the actual version
$current_ps_version = [version]"$($PSVersionTable.PSVersion.Major).$($PSVersionTable.PSVersion.Minor)"
if ($current_ps_version -eq [version]$version) {
Write-Log -message "current and target PS version are the same, no action is required"
Clear-AutoLogon
exit 0
}
$os_version = [Version](Get-Item -Path "$env:SystemRoot\System32\kernel32.dll").VersionInfo.ProductVersion
$architecture = $env:PROCESSOR_ARCHITECTURE
if ($architecture -eq "AMD64") {
$architecture = "x64"
} else {
$architecture = "x86"
}
$actions = @()
switch ($version) {
"3.0" {
$actions += "3.0"
break
}
"4.0" {
if ($os_version -lt [version]"6.1") {
$error_msg = "cannot upgrade Server 2008 to Powershell v4, v3 is the latest supported"
Write-Log -message $error_msg -level "ERROR"
throw $error_msg
}
$actions += "4.0"
break
}
"5.1" {
if ($os_version -lt [version]"6.1") {
$error_msg = "cannot upgrade Server 2008 to Powershell v5.1, v3 is the latest supported"
Write-Log -message $error_msg -level "ERROR"
throw $error_msg
}
# check if WMF 3 is installed, need to be uninstalled before 5.1
if ($os_version.Minor -lt 2) {
$wmf3_installed = Get-Hotfix -Id "KB2506143" -ErrorAction SilentlyContinue
if ($wmf3_installed) {
$actions += "remove-3.0"
}
}
$actions += "5.1"
break
}
default {
$error_msg = "version '$version' is not supported in this upgrade script"
Write-Log -message $error_msg -level "ERROR"
throw $error_msg
}
}
# detect if .NET 4.5.2 is not installed and add to the actions
$dotnet_path = "HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full"
if (-not (Test-Path -Path $dotnet_path)) {
$dotnet_upgrade_needed = $true
} else {
$dotnet_version = Get-ItemProperty -Path $dotnet_path -Name Release -ErrorAction SilentlyContinue
if ($dotnet_version) {
# 379893 == 4.5.2
if ($dotnet_version.Release -lt 379893) {
$dotnet_upgrade_needed = $true
}
} else {
$dotnet_upgrade_needed = $true
}
}
if ($dotnet_upgrade_needed) {
$actions = @("dotnet") + $actions
}
Write-Log -message "The following actions will be performed: $($actions -join ", ")"
foreach ($action in $actions) {
$url = $null
$file = $null
$arguments = "/quiet /norestart"
switch ($action) {
"dotnet" {
Write-Log -message "running .NET update to 4.5.2"
$url = "https://download.microsoft.com/download/E/2/1/E21644B5-2DF2-47C2-91BD-63C560427900/NDP452-KB2901907-x86-x64-AllOS-ENU.exe"
$error_msg = "failed to update .NET to 4.5.2"
$arguments = "/q /norestart"
break
}
"remove-3.0" {
# this is only run before a 5.1 install on Windows 7/2008 R2, the
# install zip needs to be downloaded and extracted before
# removing 3.0 as then the FileSystem assembly cannot be loaded
Write-Log -message "downloading WMF/PS v5.1 and removing WMF/PS v3 before version 5.1 install"
Download-Wmf5Server2008 -architecture $architecture > $null
$file = "wusa.exe"
$arguments = "/uninstall /KB:2506143 /quiet /norestart"
break
}
"3.0" {
Write-Log -message "running powershell update to version 3"
if ($os_version.Minor -eq 1) {
$url = "https://download.microsoft.com/download/E/7/6/E76850B8-DA6E-4FF5-8CCE-A24FC513FD16/Windows6.1-KB2506143-$($architecture).msu"
} else {
$url = "https://download.microsoft.com/download/E/7/6/E76850B8-DA6E-4FF5-8CCE-A24FC513FD16/Windows6.0-KB2506146-$($architecture).msu"
}
$error_msg = "failed to update Powershell to version 3"
break
}
"4.0" {
Write-Log -message "running powershell update to version 4"
if ($os_version.Minor -eq 1) {
$url = "https://download.microsoft.com/download/3/D/6/3D61D262-8549-4769-A660-230B67E15B25/Windows6.1-KB2819745-$($architecture)-MultiPkg.msu"
} else {
$url = "https://download.microsoft.com/download/3/D/6/3D61D262-8549-4769-A660-230B67E15B25/Windows8-RT-KB2799888-x64.msu"
}
$error_msg = "failed to update Powershell to version 4"
break
}
"5.1" {
Write-Log -message "running powershell update to version 5.1"
if ($os_version.Minor -eq 1) {
# Server 2008 R2 and Windows 7, already downloaded in remove-3.0
$file = Download-Wmf5Server2008 -architecture $architecture
} elseif ($os_version.Minor -eq 2) {
# Server 2012
$url = "http://download.microsoft.com/download/6/F/5/6F5FF66C-6775-42B0-86C4-47D41F2DA187/W2K12-KB3191565-x64.msu"
} else {
# Server 2012 R2 and Windows 8.1
if ($architecture -eq "x64") {
$url = "http://download.microsoft.com/download/6/F/5/6F5FF66C-6775-42B0-86C4-47D41F2DA187/Win8.1AndW2K12R2-KB3191564-x64.msu"
} else {
$url = "http://download.microsoft.com/download/6/F/5/6F5FF66C-6775-42B0-86C4-47D41F2DA187/Win8.1-KB3191564-x86.msu"
}
}
break
}
default {
$error_msg = "unknown action '$action'"
Write-Log -message $error_msg -level "ERROR"
}
}
if ($file -eq $null) {
$filename = $url.Split("/")[-1]
$file = "$tmp_dir\$filename"
}
if ($url -ne $null) {
Download-File -url $url -path $file
}
$exit_code = Run-Process -executable $file -arguments $arguments
if ($exit_code -ne 0 -and $exit_code -ne 3010) {
$log_msg = "$($error_msg): exit code $exit_code"
Write-Log -message $log_msg -level "ERROR"
throw $log_msg
}
if ($exit_code -eq 3010) {
Reboot-AndResume
break
}
}