Hello LucD,
I am using this script to install windows hotfix on multiple versions of windows in one go.
But here I am facing few challenges with the script. Is there any way to correct the existing script or modify for installing hotfix on multiple version of windows.
1. Copy-VMGuestFile is trying with all the wrong password and if any password works it is copying but again it is trying to copy with rest of other password and giving on error. 'Authentication failed'
2. After copying the hotfix it should try to install the hotfix by using Invoke-VMScript which is in next line but that is not happening for the copied vms.
$accounts = @(
@{
User = 'administrator'
Pswd = 'test@1'
},
@{
User = 'administrator'
Pswd = 'test@123'
},
@{
User = 'administrator'
Pswd = 'test@1234'
},
@{
User = 'admin'
Pswd = 'test@1234'
}
@{
User = 'admin1'
Pswd = 'test@1234'
}
@{
User = 'admin2'
Pswd = 'test@123'
}
@{
User = 'admin2'
Pswd = 'test@1'
}
)
$vm=Get-VM | Where-Object { $_.PowerState -eq "Poweredon" -and $_.ExtensionData.Config.GuestFullName -like "*Microsoft*" } | Select-Object Name, @{N = 'OsVersion'; E = { $_.ExtensionData.Config.GuestFullName }}
#windows2008r2
if($windows2008r2 = $vm | Where-Object { $_.OsVersion -eq 'Microsoft Windows Server 2008 R2 (64-bit)' }) {
$script2008r2 = @'
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs; exit }
wusa.exe C:\windows6.1-kb4512506-x64_84e26e414da5d56991c15de19a93824d23b82e89.msu /quiet /norestart
'@
$windows2008r2.Name | ForEach-Object -Process {
foreach ($user in $accounts) {
try {
$sInvoke = @{
VM = $windows2008r2.Name
GuestUser = $user.User
GuestPassword = $user.Pswd
ScriptText = $script2008r2
ScriptType = 'Powershell'
ErrorAction = 'Stop'
}
Copy-VMGuestFile -Source "C:\Users\Administrator\Videos\2k8R264\windows6.1-kb4512506-x64_84e26e414da5d56991c15de19a93824d23b82e89.msu" -Destination 'C:\' -LocalToGuest -VM $windows2008r2.Name -GuestUser $user.user -GuestPassword $user.Pswd -Force
Invoke-VMScript @sInvoke
break
}
catch {
}
}
}
}
#windows2012
elseif ($windows2012 = $vm | Where-Object { $_.OsVersion -eq 'Microsoft Windows Server 2012 (64-bit)' }) {
$script2012 = @'
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs; exit }
wusa.exe C:\windows8.1-kb4512488-x64_d5a1a3f96004791981bf0d469e724fb97be4377d.msu /quiet /norestart
'@
$windows2012.Name | ForEach-Object -Process {
foreach ($user in $accounts) {
try {
$sInvoke = @{
VM = $windows2012.Name
GuestUser = $user.User
GuestPassword = $user.Pswd
ScriptText = $script2012
ScriptType = 'Powershell'
ErrorAction = 'Stop'
}
Copy-VMGuestFile -Source 'C:\Users\Administrator\Videos\2012R2\windows8.1-kb4512488-x64_d5a1a3f96004791981bf0d469e724fb97be4377d.msu' -Destination 'C:\' -LocalToGuest -VM $windows2012.Name -GuestUser $user.user -GuestPassword $user.Pswd -Force
Invoke-VMScript @sInvoke
break
}
catch {
}
}
}
}
#Windows 7 64Bit
elseif ($windows764bit = $vm | Where-Object { $_.OsVersion -eq 'Microsoft Windows 7 (64-bit)' }) {
$scriptwin764bit = @'
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs; exit }
wusa.exe C:\windows6.1-kb4512506-x64_84e26e414da5d56991c15de19a93824d23b82e89.msu /quiet /norestart
'@
$windows764bit.Name | ForEach-Object -Process {
foreach ($user in $accounts) {
try {
$sInvoke = @{
VM = $windows764bit.Name
GuestUser = $user.User
GuestPassword = $user.Pswd
ScriptText = $scriptwin764bit
ScriptType = 'Powershell'
ErrorAction = 'Stop'
}
Copy-VMGuestFile -Source "C:\Users\Administrator\Videos\win764\windows6.1-kb4512506-x64_84e26e414da5d56991c15de19a93824d23b82e89.msu" -Destination 'C:\' -LocalToGuest -VM $windows764bit.Name -GuestUser $user.user -GuestPassword $user.Pswd -Force
Invoke-VMScript @sInvoke
break
}
catch {
}
}
}
}
#windows7-32 Bit
elseif ($windows732bit = $vm | Where-Object { $_.OsVersion -eq 'Microsoft Windows 7 (32-bit)' }) {
$scriptwin732bit = @'
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs; exit }
wusa.exe C:\windows6.1-kb4512506-x86_12e5961df2895fc5d45f19910702f2a49fcb08a9.msu /quiet /norestart
'@
$windows732bit.Name | ForEach-Object -Process {
foreach ($user in $accounts) {
try {
$sInvoke = @{
VM = $windows732bit.Name
GuestUser = $user.User
GuestPassword = $user.Pswd
ScriptText = $scriptwin732bit
ScriptType = 'Powershell'
ErrorAction = 'Stop'
}
Copy-VMGuestFile -Source 'C:\Users\Administrator\Videos\win732\windows6.1-kb4512506-x86_12e5961df2895fc5d45f19910702f2a49fcb08a9.msu' -Destination 'C:\' -LocalToGuest -VM $windows732bit.Name -GuestUser $user.user -GuestPassword $user.Pswd -Force
Invoke-VMScript @sInvoke
break
}
catch {
}
}
}
}
# Windows 2016
else {
($windows2016 = $vm | Where-Object { $_.OsVersion -eq 'Microsoft Windows Server 2016 (64-bit)' })
$scriptwin2016 = @'
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs; exit }
wusa.exe C:\windows10.0-kb4512517-x64_81ba5a17cf768a54489faf28ba3a3eca3c0c36d5.msu /quiet /norestart
'@
$windows2016.Name | ForEach-Object -Process {
foreach ($user in $accounts) {
try {
$sInvoke = @{
VM = $windows2016.Name
GuestUser = $user.User
GuestPassword = $user.Pswd
ScriptText = $scriptwin2016
ScriptType = 'Powershell'
ErrorAction = 'Stop'
}
Copy-VMGuestFile -Source 'C:\Users\Administrator\Videos\2k1664\windows10.0-kb4512517-x64_81ba5a17cf768a54489faf28ba3a3eca3c0c36d5.msu' -Destination 'C:\' -LocalToGuest -VM $windows2016.Name -GuestUser $user.user -GuestPassword $user.Pswd -Force
Invoke-VMScript @sInvoke
break
}
catch {
}
}
}
}
You don't seem to have the -ErrorAction Stop on the Copy-VMGuestFile cmdlet.
As a result it will never enter the catch-block.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Ok understood., so when it try’s with wrong password then it will gives the error.
But my 2 point which I mentioned after copying in the next step it should invoke but that is not happening why?
is this a correct approach by using multiple if statements for executing on multiple versions of os with os specific patch.
You should probably first do the procedure for the credentials for Invoke-VMScript.
Once you have those, you can do the Invoke-VMScript and the Copy-VMGuestFile with the same credentials.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference