I recently updated PSWindowsUpdate from version 1.6.1.1 to the latest version (2.1.0.1) and when I try to run the script:
Write-Host " Centralized Update"
Write-Host "================================"
ipmo activedirectory
$computers = Get-ADComputer -Filter {enabled -eq $true} -properties * -SearchBase "OU=Workstations, DC=contoso, DC=com" | select name
$Script = {ipmo PSWindowsUpdate; Get-WUInstall -AcceptAll -Install -Verbose}
foreach ($computer in $computers) {
Write-Host "Running update on:" $computer.name
Invoke-WUJob -ComputerName $computer.name -Script $Script -Confirm:$false -RunNow
}
Write-Host "================================"
pause
I get the following error:
Invoke-WUJob : The system cannot find the file specified. (Exception from HRESULT: 0x80070002)
At C:\Users\Administrator\Desktop\Update_Workstations.ps1:10
char:2
+ Invoke-WUJob -ComputerName $computer.name -Script $Script -Confir ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Invoke-WUJob], FileNotFoundException
+ FullyQualifiedErrorId : System.IO.FileNotFoundException,PSWindowsUpdate.InvokeWUJob
The only edit to the script was to change:
Invoke-WUInstall -ComputerName $computer.name -Script $Script -Confirm:$false
To:
Invoke-WUJob -ComputerName $computer.name -Script $Script -Confirm:$false -RunNow
More details:
The version of PowerShell is 5.1 (both client and server side)
The list of terminals is correctly extracted from the "Workstations" organizational unit
I can connect via "enter-pssession" to all the terminals without problems
Using "Invoke-Command" instead of "Invoke-WUJob" run but fails at the time of download with the error "UnauthorizedAccessException"
What's wrong with the code ? before updating to version 2.1.0.1 it works fine
I was also getting the same error. By scratching my head for a day finally a found one power shell command needs to run on the target server before proceeding invoke-wujob
the command is Enable-WURemoting
Related
Source is Windows and destination is Ubuntu (installed on VMware player).
I ran below script in Windows:
$targetComputerName = "192.168.22.130"
$Username = 'zahid'
$Password = 'Z#hid1212'
$Pass = ConvertTo-SecureString -AsPlainText $Password -Force
$SecureString= $pass
$MySecureCreds = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $Username,$SecureString
$Session = New-PSSession $targetComputerName -Credential $MySecureCreds
$DestinationPath = "/home/zahid/Downloads"
$Source = 'D:\zahid.txt'
Copy-Item -Path $Source -ToSession $Session -Destination $DestinationPath
$Session | Remove-PSSession
and got error:
New-PSSession : [192.168.22.130] Connecting to remote server 192.168.22.130 failed with the following error message : The client cannot connect to the destination
specified in the request. Verify that the service on the destination is running and is accepting requests. Consult the logs and documentation for the WS-Management
service running on the destination, most commonly IIS or WinRM. If the destination is the WinRM service, run the following command on the destination to analyze and
configure the WinRM service: "winrm quickconfig". For more information, see the about_Remote_Troubleshooting Help topic.
At C:\Users\DELL\Desktop\Untitled1.ps1:8 char:12
+ $Session = New-PSSession $targetComputerName -Credential $MySecureCre ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OpenError: (System.Manageme....RemoteRunspace:RemoteRunspace) [New-PSSession], PSRemotingTransportException
+ FullyQualifiedErrorId : CannotConnect,PSSessionOpenFailed
Copy-Item : Cannot validate argument on parameter 'ToSession'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command
again.
At C:\Users\DELL\Desktop\Untitled1.ps1:12 char:36
+ Copy-Item -Path $Source -ToSession $Session -Destination $Destination ...
+ ~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Copy-Item], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.CopyItemCommand
Do I need to setup winrm service on destination (here is Ubuntu) also? How can I achieve that?
I used to use WinScp with PowerShell, or Posh-SSH.
These two ways allow you exploit conventional SSH on Linux.
Begining with PowerShell 6 you can use PowerShell remoting over SSH, this link show you the setup on Windows and Ubuntu.
Even though the below script runs successfully to remove software, I
am still able to see the software in the control panel program list,
what I am doing wrong?
See the command below :
PS D:\Project> .\ScriptWithBelowCode.ps1 -ComputerName
"X-XXX50947" -AppGUID XXXXXX-A60B-4899-A369-XXXXXXX
Uninstallation command triggered successfully
[cmdletbinding()]
param (
[parameter(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
[string]$ComputerName = $env:computername,
[parameter(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Mandatory=$true)]
[string]$AppGUID
)
try {
$returnval = ([WMICLASS]"\\$computerName\ROOT\CIMV2:win32_process").Create("msiexec `/x$AppGUID `/norestart `/qn")
} catch {
write-error "Failed to trigger the uninstallation. Review the error message"
$_
exit
}
switch ($($returnval.returnvalue)){
0 { "Uninstallation command triggered successfully" }
2 { "You don't have sufficient permissions to trigger the command on $Computer" }
3 { "You don't have sufficient permissions to trigger the command on $Computer" }
8 { "An unknown error has occurred" }
9 { "Path Not Found" }
9 { "Invalid Parameter"}
}
Command to execute .\ScriptFileWithAboveContent.ps1 -ComputerName "X-15XX150947" -AppGUID 30F836D2-A60B-4899-A369-XXXXX884EAF
Command to get GUID
Get-WmiObject -Class Win32_Product ` -Filter "Name like '%Microsoft%'" | Select-Object -ExpandProperty IdentifyingNumber
Second try
$app = Get-WmiObject -Class Win32_Product | Where-Object {$_.IdentifyingNumber -match "XXXXXX-A60B-4899-XXXX-B0FXXX84EAF" }
$app.Uninstall()
I am getting error showing below
PS D:\Project> .\ScriptFileWithAboveContent.ps1
Exception calling "Uninstall" : "Operation is not valid due to the current state of the object."
At D:\MicrosoftAIM\ScriptFileWithAboveContent.ps1:2 char:5
+ $app.Uninstall()
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : WMIMethodException
Third try
The below script ran successfully, But still, the software is still in the program list.
echo "Getting product code"
$ProductCode = Get-WmiObject win32_product -Filter "Name like '%somesoftware%'" | Select-Object -Expand IdentifyingNumber
echo "removing Product"
# Out-Null argument is just for keeping the power shell command window waiting for msiexec command to finish else it moves to execute the next echo command
& msiexec /x $ProductCode | Out-Null
echo "uninstallation finished"
PS D:\MicrosoftAIM> .\ScriptWithAboveContent.ps1
Getting product code
removing Product
uninstallation finished
PS D:\MicrosoftAIM> Get-WmiObject -Class Win32_Product ` -Filter "Name like '%Microsoft%azure%info%'"
I'm trying to run a powershell script from rundeck(linux), If I run the script locally[Deletes some files from multiple terminal servers](Windows server) it is working as expected however if I call it from rundeck server(winrm configured) it seems that the script cant access the remote folders I'm trying to access.
I tried running the script using the same user but still shows different result.
Script bellow:
$userAD = "someuser"
$servers = Get-Content C:\TSList.csv
$Folder = "c$\Users\$userAD\"
$TSFolderShare = "\\sharepath"
Write-Output "#####Start of script#####"
Write-output `n
Write-output "Checking if $userAD user profile exist in Terminal servers..."
sleep -seconds 1
foreach ($server in $servers) {
Test-Path "\\$server\$Folder" -PathType Any
Get-ChildItem "\\$server\$Folder"
if (Test-Path "\\$server\$Folder" -PathType Any) {
Write-output "Resetting user profile in $server.."
Get-ChildItem "\\$server\$Folder" -Recurse -Force -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
sleep -seconds 1
Write-output "Done."
if( (Get-ChildItem "\\$server\$Folder" | Measure-Object).Count -eq 0)
{
Write-output "Done."
}
}
else
{
Write-output "Resetting user profile in $server.."
sleep -seconds 1
Write-output "User profile does not exist in $server."
#Write-output "\\$server\$Folder does not exist in $server!" -ForegroundColor Red
}
}
EDIT: It seems my problem is when running my script from another script with RunAS.
Below I'm trying to access a folder from another server using ps script, but since I want to integrate this to Rundeck I need to call my ps script from my linux server using python. I did a test running the ps script directly and calling the test path script using another script with RunUs using the same user I used to run the script manually
Scenario 1
Running PS script via separate PS script with RunAS(my_account)
$username = "my_account"
$password = "my_password"
$secstr = New-Object -TypeName System.Security.SecureString
$password.ToCharArray() | ForEach-Object {$secstr.AppendChar($_)}
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $secstr
Invoke-Command -FilePath "C:\testpath.ps1" -Credential $cred -Computer localhost
(C:\testpath.ps1) Content below:
Test-Path "\\server\c$\Users\myaccount\"
result:
Access is denied
+ CategoryInfo : PermissionDenied: (\server\c$\Users\myaccount:String) [Test-Path], UnauthorizedAccessException
+ FullyQualifiedErrorId : ItemExistsUnauthorizedAccessError,Microsoft.PowerShell.Commands.TestPathCommand
+ PSComputerName : localhost
False
Scenario 2
Running C:\testpath.ps1 directly as my_account
Test-Path "\\server\c$\Users\myaccount\"
result:
True
I used session configuration in powershell to solve the issue. This way allows you to tie a credential to a PowerShell session configuration and reuse this configuration for all future connections.
https://4sysops.com/archives/solve-the-powershell-multi-hop-problem-without-using-credssp/
Thanks a lot!
You're facing a double-hop issue with Rundeck and Powershell, here the explanation. That's asked before, take a look a this, and here a good workaround. Also this to solve it.
I just set up a few containerized agents and I'm running into build issues with few regression tests which work fine on regular build agents.
Was wondering if anyone had issues with containerized build agents?
Error Log:
Add-Type : (0) : Unable to find messages file 'cscui.dll' (1) : namespace VstsTaskSdk.FS At C:\tfsagent_work_tasks\VSBuild_71a9a2d3-a98a-4caa-96ab-affca411ecda\1.119.0\ps_modules\VstsTaskSdk\LongPathFunctions.ps1:212 char:1 + Add-Type -Debug:$false -TypeDefinition #' + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidData: (Microsoft.Power...peCompilerError:AddTypeCompilerError) [Add-Type], Exception + FullyQualifiedErrorId : SOURCE_CODE_ERROR,Microsoft.PowerShell.Commands.AddTypeCommand
#
Unable to find type [VstsTaskSdk.TerminationException]. Exit code 1
returned from process: file name
'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe', arguments
'-NoLogo -Sta -NoProfile -NonInteractive -ExecutionPolicy Unrestricted
-Command ". ([scriptblock]::Create('if (!$PSHOME) { $null = Get-Item -LiteralPath ''variable:PSHOME'' } else { Import-Module -Name ([System.IO.Path]::Combine($PSHOME,
''Modules\Microsoft.PowerShell.Management\Microsoft.PowerShell.Management.psd1''))
; Import-Module -Name ([System.IO.Path]::Combine($PSHOME,
''Modules\Microsoft.PowerShell.Utility\Microsoft.PowerShell.Utility.psd1''))
}')) 2>&1 | ForEach-Object { Write-Verbose $_.Exception.Message
-Verbose } ; Import-Module -Name 'C:\tfsagent_work_tasks\VSBuild_71a9a2d3-a98a-4caa-96ab-affca411ecda\1.119.0\ps_modules\VstsTaskSdk\VstsTaskSdk.psd1'
-ArgumentList #{ NonInteractive = $true } -ErrorAction Stop ; $VerbosePreference = 'SilentlyContinue' ; $DebugPreference =
'SilentlyContinue' ; Invoke-VstsTaskScript -ScriptBlock
([scriptblock]::Create('.
''C:\tfsagent_work_tasks\VSBuild_71a9a2d3-a98a-4caa-96ab-affca411ecda\1.119.0\VSBuild.ps1'''))"'.
I'm very new to PowerShell (forgive my ignorance) and am trying to install a program remotely on multiple computers on my domain. Currently, I'm just trying to get it to work on one computer. The script below was found online and adapted for my needs. Yesterday it worked, but today it's complaining about the session parameter.
I don't fully understand "sessions", but I have ensured on the client machine that the winrm service is running and I have invoked Enable-PSRemoting -force.
Here's the script:
$computers = Get-Content "c:\tmpPS\computers.txt"
$rs = Get-PSSession
Get-PSSession | Get-Member
######
## Functions
################
foreach ($comp in $computers)
{
Write-Host "should work with $comp"
}
PushMSI
RemoteConnect
InstallMSI
Function PushMSI {
Write-Host "------------------------------------------------"
Write-Host "This will copy the MSI file from localhost c:\tmpPS\"
write-Host "------------------------------------------------"
Write-Host ""
Write-Host ""
foreach ($comp in $computers)
{
Copy-Item -path "c:\tmpPS\clientInstall.msi" -Destination \\$comp\c$\tmpPS
}
}
Function RemoteConnect
{
Write-Host "------------------------------------------------"
Write-Host "This will establish a PSSession with all computers in c:\temp\computers.txt"
write-Host "------------------------------------------------"
Write-Host ""
Write-Host ""
Get-Content C:\tmpPS\computers.txt | New-PSSession -ThrottleLimit 50
}
Function InstallMSI
{
Write-Host "------------------------------------------------"
Write-Host "This will Install UPS Update on all computers with an Established PSSession"
write-Host "------------------------------------------------"
Write-Host "After the Install PSSessions will be removed"
Write-Host ""
Invoke-Command -Session $rs -ScriptBlock {invoke-item "c:\tmpPS\ClientInstall.msi"}
}
Get-PSSession | Remove-PSSession
And here's the output:
PS C:\Users\Me> C:\tmpPS\remoteInstall.ps1
Get-Member : No object has been specified to the get-member cmdlet.
At C:\tmpPS\remoteInstall.ps1:3 char:17
+ Get-PSSession | Get-Member
+ ~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [Get-Member], InvalidOperationException
+ FullyQualifiedErrorId : NoObjectInGetMember,Microsoft.PowerShell.Commands.GetMemberCommand
should work with eSignWin81.informa.local
------------------------------------------------
This will copy the MSI file from localhost c:\tmpPS\
------------------------------------------------
------------------------------------------------
This will establish a PSSession with all computers in c:\temp\computers.txt
------------------------------------------------
Id Name ComputerName State ConfigurationName Availability
-- ---- ------------ ----- ----------------- ------------
6 Session6 eSignWin81.i... Opened Microsoft.PowerShell Available
------------------------------------------------
This will Install UPS Update on all computers with an Established PSSession
------------------------------------------------
After the Install PSSessions will be removed
Invoke-Command : Cannot validate argument on parameter 'Session'. The argument is null or empty. Supply an argument that is not null or empty and then try
the command again.
At C:\tmpPS\remoteInstall.ps1:49 char:25
+ Invoke-Command -Session $rs -ScriptBlock {invoke-item "c:\tmpPS\ClientInstall.ms ...
+ ~~~
+ CategoryInfo : InvalidData: (:) [Invoke-Command], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.InvokeCommandCommand
Try not to use Write-Host as it brakes the pipeline and kills puppy's.
I've tried to improve your script a little bit, so you understand the logic behind the structure better. It hasn't been tested, but it should do the trick.
# First parameters
[CmdletBinding()]
Param(
[ValidateScript({Test-Path $_ -PathType leaf})]
$ComputerList = "c:\tmpPS\computers.txt",
[ValidateScript({Test-Path $_ -PathType leaf})]
$MSI = "c:\tmpPS\clientInstall.msi"
)
# Then functions
Begin {
Function Copy-MSI {
foreach ($Com in $Computers) {
Copy-Item -path $MSI -Destination "\\$Com\c$\tmpPS"
}
}
Function Install-MSI {
foreach ($Com in $Computers) {
Enter-PSSession -ComputerName $Com
invoke-item "c:\tmpPS\ClientInstall.msi"
Exit-PSSession
}
}
}
# Then the actions
Process {
$Computers = Get-Content $ComputerList
Copy-MSI
Install-MSI
}
If you run this, you'll find the information you're looking for:
Get-Help Enter-PSSession