When I want to manually install multiple windows security patch with a one restart, one of the security patches is installed and 0x800f0840 error occurs for the others. I don't want to restart for every patch. How can I do that?
I'm doing multi-loading with the powershell code below.
$dir = (Get-Item -Path ".\" -Verbose).FullName
Foreach($item in (ls $dir *.msu -Name))
{
echo $item
$item = $dir + "\" + $item
wusa $item /quiet /norestart | Out-Null
}
Related
I'm trying to get a script together to remotely install some windows updates on some remote servers that are connected in an offline domain.
I have tried regular PS Remoting and after some research, I think what I am trying to do isnt supported by microsoft. When checking my event logs I have a bunch of these errors.
Edit
I wanted to add that I have tried running the .\Install2012R2.ps1 script from my local computer, modified to have the Invoke-Command in that and have it run the update portion of the original Install2012R2.ps1 and I would get the same errors.
I was hoping that by placing the script on each server that it would like that more.
End Edit
Windows update could not be installed because of error 2147942405 "Access is denied."
(Command line: ""C:\Windows\System32\wusa.exe" "C:\Updates\windows8.1-kb4556853-x64.msu" /quiet /norestart")
I have tried running Invoke-Command as credentialed to an administrator account on the servers but I have been having no luck and was looking for some advice if someone has maybe tried/done this before.
$Servers = #("V101-Test1","V101-Test2")
$Username = 'admin'
$Password = 'Password'#not actual password
$pass = ConvertTo-SecureString -AsPlainText $Password -Force
$Cred = New-Object System.Management.Automation.PSCredential -ArgumentList $Username,$pass
Get-PSSession | Remove-PSSession
New-PSSession -ComputerName $Servers
foreach($Server in $Servers){
Get-ChildItem -Path C:\Source\Temp -Recurse | Copy-Item -Destination "\\$Server\c$\Updates\" -Force
}
Invoke-Command $Servers -Credential $Cred -ScriptBlock{
& "C:\Updates\Install2012R2.ps1"
}
EDIT 2
Here is the actual install code of the Install2012R2.ps1 script
$updatedir= "./"
$files = Get-ChildItem $updatedir -Recurse
$msus = $files | ? {$_.extension -eq ".msu"}
$exes = $files | ? {$_.extension -eq ".exe"}
foreach ($file in $msus){
$KBCtr++
$fullname = $file.fullname
# Need to wrap in quotes as folder path may contain space
$fullname = "`"" + $fullname + "`""
$KBN = $fullname.split('-')[1]
# Need to wrap in quotes as folder path may contain space
$fullname = "`"" + $fullname + "`""
# Specify the command line parameters for wusa.exe
$parameters = $fullname + " /quiet /norestart"
# Start services and pass in the parameters
$install = [System.Diagnostics.Process]::Start( "wusa",$parameters )
$install.WaitForExit()
}
I'm not sure why wusa.exe is failing here with Access Denied, but here is a PowerShell-native approach you can try. If nothing else, it should give you a clearer indication via the captured error information as to what the underlying issue is:
Add-WindowsPackage -Path C:\Updates\OurHeroicUpdate.msu -Online -PreventPending -NoRestart
-Path is the path to the msu file
-Online tells Add-WindowsPackage to modify the currently "mounted image" (the running version) of Windows (as opposed to an offline disk image you could also apply it to)
-PreventPending prevents installing the msu if there is already a pending change, like needing to reboot for updates.
Add-WindowsPackage is part of the DISM module available under Windows PowerShell, and is the functional equivalent of dism /packagepath:"cabfile", although it can take an msu where dism.exe only allows a cab.
I have created my first PowerShell script to mass delete user profiles, For the most part it works fine, however, it does occasionally leave behind some profiles that cannot be found in Powershell when Get-CimInstance win32_UserProfile is run.
Even though PowerShell seemingly does not see these profiles they do get touched by the script so that their last accessed date is current, everything aside from their appdata folders are deleted, and they are still in the C:\Users directory.
The only solution I have currently is to manually select these profiles within Users and then delete them but I'm trying to completely automate this process. I am at a loss as to what could cause this, so any advice or guidance is greatly appreciated. Here is my code:
# Grab all the user profiles and ignore anything in our exceptions
$Profiles = Get-CimInstance Win32_UserProfile | where {((!$_.Special) -and ($_.LocalPath -ne "C:\Users\Administrator") -and ($_.LocalPath -ne "C:\Users\admin1") -and ($_.LocalPath -ne "C:\Users\admin2") -and ($_.LocalPath -ne "C:\Users\admin3") -and ($_.LocalPath -ne "C:\Users\admin4"))}
# Get the number of profiles to use in -PercentComplete
$ProfilesCount = $Profiles.Count
# This for loop iterates through profiles and deletes them as well as creates our progress bar
Function ProfilesB-Gone
{
for ($i = 1; $i -lt $ProfilesCount; $i++)
{
# Our progress bar is generated and updated
Write-Progress -Activity 'Removing Profiles' -Status "Deleted $i out of $ProfilesCount profiles" -PercentComplete (($i/$ProfilesCount) * 100)
# Here we're suppressing errors and continuing while deleting our profiles
Remove-CimInstance $Profiles[$i] -EV Err -EA SilentlyContinue
}
# Remove progress bar once complete
Write-Progress -Activity 'Removing Profiles' -Status 'Complete!' -Completed
}
# Call function
ProfilesB-Gone;
# Remove all leftover profiles that remain ocasionally due to noncritical and inconsistent bug and suppress errors. Not suppressing errors causes as many error windows to show as there were $ProfilesCount.
$Profiles | Remove-CimInstance -EV Err -EA SilentlyContinue
# Give success message to inform user of script completion
Write-Host "Profiles Deleted!"
A win10 app (MicrosoftOfficeHub) makes strange links that can't be deleted in the normal way. Using something like cmd /c rmdir /s /q c:\users\user still works, when powershell and wmi don't. How to remove user profile completely from the Windows 10 computer?
I want a Powershell script that will allow:
Deletion of keys in the Windows registry corresponding to 10.x.x.x (if not present proceed to step 2)
Delete an entry in the Windows Vault : 10.x.x.x (if not present proceed to step 3)
Add a printer by name \ 10.x.x.x \ Printer + Authentication on print server (Domain \ User with password by memorizing the information in the Windows Vault)
For my part I tried this :
Write-Output "===========Deleting entry Windows Vault==========="
cmdkey /delete:10.x.x.x
Start-Sleep -s 5
Write-Output "===========Deleting printer==========="
Remove-Printer -Name "\10.x.x.x\PrinterName"
Start-Sleep -s 5
Write-Output "===========Deleting old entries Windows registry==========="
Get-Childitem -path hkcu:\ -recurse -ErrorAction SilentlyContinue |
Where-Object {$.Name -like "*10.x.x.x*"} |
ForEach-Object {Remove-Item $.FullName}
Start-Sleep -s 5
Write-Verbose "===========Configuration printer==========="
$cred = get-credential "DomainName\" $domain = "."
$user = $cred.UserName
$PrinterPath = "\10.x.x.x\PrinterName"
$net = new-Object -com WScript.Network
$pwd = $cred.Password
$net.AddWindowsPrinterConnection($PrinterPath)
Start-Sleep -s 5
It is not very conclusive...
In the example above, is it possible to adapt the script ?
For example, if you want to delete the registry keys and the Windows Vault entry, if the executed command does not find the requested information, make sure you do nothing and proceed to the next step.
Would it be possible to have help please ?
Thank you !
Have a good day.
Currently experiencing issue, I'm currently doing this:
Get-ChildItem $PATH -Recurse -ErrorAction SilentlyContinue |
Where-Object {($_.Attributes -notmatch '\"Directory\"') -and
($_.LastWriteTime -lt (Get-Date).AddHours(-12))}|
Remove-Item -Force -Recurse
Now, it would delete fine IF I didn't have symlinks, but I do. I am getting this error:
Remove-Item : There is a mismatch between the tag specified in the request and the tag present in the reparse point
At line:1 char:184
+ ... ($_.LastWriteTime -lt (Get-Date).AddHours(-12))}| Remove-Item -Force
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Remove-Item], Win32Exception
+ FullyQualifiedErrorId : System.ComponentModel.Win32Exception,Microsoft.PowerShell.Commands.RemoveItemCommand
I'm unable to upgrade powershell to v6. It seems to be related to:https://github.com/powershell/powershell/issues/621#issuecomment-289230180
Anyone have a workaround?
Tested today on PowerShell 7 and unfortunately the issue is still there: PowerShell cannot delete symlink.
I had to delete the directory through an elevated prompt typing cmd /c rmdir /s /q C:\Users\Your_User_Name\Your_Folder_Name
This problem seems to be fixed in PS 6 (ref: https://github.com/powershell/powershell/issues/621)
In PS 5.1 one can work around it by using:
$(get-item $theSymlinkDir).Delete()
or as LotPings noted in the comments to the Q for this specific Foreach-Object loop:
|? LinkType -eq 'SymbolicLink'| % { $_.Delete() }
I'm writing simple script to unarchive (rar) a project from Teamcenter to temp directory, then run specific program (Mentor), then archive again.
I've read a lot of examples about starting exe from PS, but they mostly relate to small exes like notepad, without dlls and other resources.
In Powershell Ise the script works perfectly. But when I call the script from teamcenter, Mentor is missing dlls.
Before I run Mentor, in the script, I do:
Get-ChildItem Env:
to check environment variables and all variables exist. I tried to set environments manually, like this:
$wf_classpath = Get-ChildItem Env:WF_CLASSPATH
[System.Environment]::SetEnvironmentVariable("WF_CLASSPATH", $wf_classpath.Value, "Process")
Does not work.
I tried to set homefolder:
$mentor = Start-Process $file.FullName -Wait -WorkingDirectory $workdir
Does not work.
Then I tried to call a batch file from the script with environments, does not work.
Try call cmd.exe /c ... does not work.
Full script here, works perfect only in Powershell Ise, if I call the script from other programs, exe does not start.
$shell = new-object -com shell.application
$invocation = $MyInvocation.MyCommand.Definition
$rootpath = $PSScriptRoot
$outpath = "$($PSScriptRoot)\out"
$pathtorar = "c:\Siemens\menutils\Rar.exe"
Remove-Item -Recurse -Force $outpath
New-Item $outpath -ItemType directory
$archive = get-childitem $rootpath | where { $_.extension -eq ".rar" } | Select-Object -First 1
$arglist = "x $($archive.FullName) $($outpath)"
Start-Process -FilePath $pathtorar -ArgumentList $arglist -Wait
Remove-Item -Recurse -Force $archive.FullName
$file = get-childitem $outpath -Recurse | where { $_.extension -eq ".prj" } | Select-Object -First 1
Write-Host "$(get-date -Format yyyy-MM-dd-hh-ss)
Start process: $($file.FullName)"
$mentor = Start-Process $file.FullName -Wait
$arglist = "a -m0 -r -ep1 $($archive.FullName) $($outpath)"
Start-Process -FilePath $pathtorar -ArgumentList $arglist -Wait
Remove-Item -Recurse -Force $outpath
Read-Host -Prompt "Press Enter to exit"
What's the difference between running the script from Powershell Ise and other programs?
How should I set environment variables to run the script from other scripts/programs?
Its probably that your Current directory is not correct and WorkingDirectory in my experience is buggy. The dll's will be obtained from the current directory if they are not at the regular system paths.
Use this function before Start-Process
[IO.Directory]::SetCurrentDirectory($Dir)