Powershell: Access denied error received when executing Recieve-Job - powershell

I have a small powershell script that I want to execute via Nagios monitoring for verification if a certain directory exists yes or no. When debugging and/or running the script in the Powershell ISE, every thing is OK and the desired result is produced. When scheduling the script via Nagios, I'm receiving "access denied" errors.
Lines in the script that produce the error:
$testJob = Start-Job -scriptblock {test-path $($args[0])} -credential $ipmamCredentials -argumentlist $ipmamdir
$finished = Wait-Job $testJob
$result = Receive-Job $testJob
Errors produced in Nagios:
Receive-Job : [localhost] There is an error launching the background process. Error reported: Access is denied.
At C:\Program Files\NSClient++\scripts\check_ipmam_drives.ps1:19 char:26
+ $result = Receive-Job <<<< $testJob
+ CategoryInfo : OpenError: (:) [Receive-Job], PSRemotingTransportException
+ FullyQualifiedErrorId : PSSessionStateBroken

Related

Running Windows updates from poweshell script on remote servers

I know this question has been asked a million times but I am really struggling with this and I would like to be able to add in a few extra features.
I have a list of servers which I would like to input into my script and then I would like the script to go off and check for updates on those servers. After which my aim is to get to it to ask if I want to continue giving the option to input Y/N.
Then I need it to go off and install updates without rebooting. It would be great then to tell me its finished and ask if I want to reboot.
Can anyone help? I am new to powershell and so far only got this which is erroring out.
$creds = Get-Credential
$serverlist = "C:\testlist.txt"
$session=New-PSSession -ComputerName $serverlist
Invoke-Command -Session $session -ScriptBlock {
[net.servicepointmanager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12
Install-module pswindowsupdate -force -AllowClobber
Get-WUInstall -AcceptAll
}
Get-PSSession | Remove-PSSession`
This doesn't get me anywhere and gives this error.
New-PSSession : One or more computer names are not valid. If you are trying to pass a URI, use the -ConnectionUri parameter, or pass URI objects instead of strings.
At C:\Untitled5.ps1:16 char:10
+ $session=New-PSSession -ComputerName $serverlist
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (System.String[]:String[]) [New-PSSession], ArgumentException
+ FullyQualifiedErrorId : PSSessionInvalidComputerName,Microsoft.PowerShell.Commands.NewPSSessionCommand
Invoke-Command : Cannot validate argument on parameter 'Session'. The argument is null or empty.
Provide an argument that is not null or empty, and then try the
command again.
At C:\Untitled5.ps1:17 char:25
+ Invoke-Command -Session $session -ScriptBlock {
+ ~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Invoke-Command], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.InvokeCommandCommand`

Running Powershell script using inline admin credentials to start and stop windows services

I have access as an admin on a machine and I have to Start, Stop and Restart some of the window services using the Powershell script. We don't want to have UAC prompt while running the script because only one user would have access to that machine. Also due to some specific requirements, we have to have run that script file by adding the admin credentials inside it.
Along with other solutions I have tried so far, the one close to what I am looking for is as follows
$username = "Domain\user"
$password = ConvertTo-SecureString "myPassword" -AsPlainText -Force
$psCred = New-Object System.Management.Automation.PSCredential -ArgumentList ($username, $password)
Set-Service -Name Spooler -Status Running -PassThru -Credential $psCred
But I am getting following error.
Set-Service : A parameter cannot be found that matches parameter name
'Credential'. At line:6 char:53
+ ... t-Service -Name Spooler -Status Running -PassThru -Credential $psCred
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Set-Service], ParameterBindingException
+ FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.SetServiceCommand
Update 1 (Trying suggestion)
Invoke-Command -credential $psCred -command {Set-Service -Name Spooler -Status Running -PassThru} -computername myComputerName
[myComputerName] Connecting to remote server myComputerName 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.
+ CategoryInfo : OpenError: (myComputerName:String) [], PSRemotingTransportException
+ FullyQualifiedErrorId : CannotConnect,PSSessionStateBroken
Update 2
I had to enabled PSRemoting on machine using command Enable-PSRemoting -Force -SkipNetworkProfileCheck so Invoke-Command can execute but after repeating the command Invoke-Command -credential $psCred -command {Set-Service -Name Spooler -Status Running -PassThru} -computername localhost I got following error
[localhost] Connecting to remote server localhost failed with the
following error message : Access is denied. For more information, see
the about_Remote_Troubleshooting Help topic.
+ CategoryInfo : OpenError: (localhost:String) [], PSRemotingTransportException
+ FullyQualifiedErrorId : AccessDenied,PSSessionStateBroken
Running the same set of command in elevated powershell window is working fine.
Can you please guide me in the right direction considering I am newbie in the Powershell world.
As mentioned in the official documentation of Set-Service
Can you try like this?
$Cred = Get-Credential
$hostname = "$env:computername.$env:userdnsdomain"
Write-Host $hostname
Invoke-Command -ComputerName $hostname -Credential $Cred -ScriptBlock{ Start-Service -Name Spooler}
Also if you don't want to prompt for the credentials then you can store the credentials in the Windows credentials manager and get it from their in your PowerShell script. Refer to this answer for using credential manager with PowerShell

PowerShell StartProcess: invalid handle

I'm trying to install google chrome on a remote machine through powershell.
This is what I'm trying to do (I've pretty much just scraped this together from a couple of other posts on various sites):
$Path = $env:TEMP;
$Installer = "chrome_installer.exe";
(new-object System.Net.WebClient).DownloadFile('http://dl.google.com/chrome/install/375.126/chrome_installer.exe', "$Path\$Installer");
Start-Process -FilePath $Path\$Installer -Args "/silent /install" -Verb RunAs -Wait;
Remove-Item $Path\$Installer
it's failing on the fourth line:
Start-Process -FilePath $Path\$Installer -Args "/silent /install" -Verb RunAs -Wait;
with the error:
Start-Process : This command cannot be run due to the error: The handle is
invalid.
At line:1 char:2
+ Start-Process -FilePath $Path\$Installer -Args "/silent /install" -V ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [Start-Process], InvalidOp
erationException
+ FullyQualifiedErrorId : InvalidOperationException,Microsoft.PowerShell.C
ommands.StartProcessCommand
I'm quite inexperienced with PowerShell and I'm having a hard time figuring out what the "handle" in the error is.
Any help is appreciated :)
EDIT:
with a try/catch { $_ | FL * -Force} around the failing command it gives this output:
PSMessageDetails :
Exception : System.InvalidOperationException: This command cannot
be run due to the error: The handle is invalid.
at System.Management.Automation.MshCommandRuntime.Th
rowTerminatingError(ErrorRecord errorRecord)
TargetObject :
CategoryInfo : InvalidOperation: (:) [Start-Process],
InvalidOperationException
FullyQualifiedErrorId : InvalidOperationException,Microsoft.PowerShell.Commands
.StartProcessCommand
ErrorDetails :
InvocationInfo : System.Management.Automation.InvocationInfo
ScriptStackTrace : at <ScriptBlock>, <No file>: line 4
PipelineIterationInfo : {}
With catching $_.Exception instead, it gives:
Message : This command cannot be run due to the error: The handle is
invalid.
Data : {}
InnerException :
TargetSite : Void ThrowTerminatingError(System.Management.Automation.ErrorR
ecord)
StackTrace : at System.Management.Automation.MshCommandRuntime.ThrowTerm
inatingError(ErrorRecord errorRecord)
HelpLink :
Source : System.Management.Automation
HResult : -2146233079
Elevation
The script would need elevation. To read about remote elevation:
https://ss64.com/ps/syntax-elevate.html
If you use Invoke-Command to run a script or command on a remote
computer, then it will not run elevated even if the local session is.
This is because any prompt for elevation will happen on the remote
machine in a non-interactive session and so will fail.
Using Enter-PSSession to start a whole new session will support
elevation if you specify CredSSP, which enables the delegation of user
credentials:
New-PSSession ss64dom.com -Auth CredSSP -cred ss64dom\user64
Zone identifier
The script could be hampered by the Internet Zone Identifier marker.
Source: http://woshub.com/how-windows-determines-that-the-file-has-been-downloaded-from-the-internet/
In PowerShell 3.0, you can display the list of files with
Zone.Identifier stream in a directory using this command:
Get-ChildItem -Recurse | Get-Item -Stream Zone.Identifier
-ErrorAction SilentlyContinue | Select-Object FileName
The attribute is removed as follows:
Remove-Item .\install-file.exe -Stream Zone.Identifier
In Windows PowerShell 4.0, you can delete Zone.Identifier using a
separate cmdlet:
Unblock-File install-file.exe
Addendum:
Remove-Item will raise an error if it does not find the alternate stream. Therefore use:
Remove-Item $Path\$Installer -Stream Zone.Identifier -ErrorAction SilentlyContinue
As far as I can tell, it comes down to the fact that in Azure Web App environments, you don't have permissions to install applications freely.
I guess management of the environment is restricted so they can guarantee a certain level of service.
You can read more about it here:
https://learn.microsoft.com/en-us/azure/app-service/choose-web-site-cloud-service-vm
try double-quoting the FilePath you are feeding the Start-Process command, OR use $(Join-Path $Path $Installer)
Right now you are escaping the $ for $Installer, so the path to the file cannot be resolved.
Start-Process -FilePath "$Path\$Installer" -Args "/silent /install" -Verb RunAs -Wait;
# OR (even better I think)
Start-Process -FilePath $(Join-Path $Path $Installer) -Args "/silent /install" -Verb RunAs -Wait;

PS4, Get-WMIObject returns PID=0 for an in-house developed service

Thanks in advance.
Here is a Powershell4 script that we're running:
$process = Get-WMiObject Win32_Service -Filter "Name ='HotKeyService'"
write-host Process Name = $process.name
write-host Process ID = $process.processid
$oopid = $process.processid
stop-process -id $oopid -force
wait-process -id $oopid -timeout 60 -WarningAction SilentlyContinue
-------------------------------
working directory: C:\Program Files\HK\HK.HotKeyService
With this I get:
Process Name = HotKeyService
Process ID = 0
Error#1
stop-process : Cannot stop process "Idle (0)" because of the following
error: Access is denied
At C:\Windows\TEMP\tmp206027652026805712.ps1:6 char:1
+ stop-process -id $oopid -force
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (System.Diagnostics.Process (Idle):P
rocess) [Stop-Process], ProcessCommandException
+ FullyQualifiedErrorId : CouldNotStopProcess,Microsoft.PowerShell.Command
s.StopProcessCommand
Error#2
wait-process : This command stopped operation because it cannot wait
on
'System Idle' process. Specify another process and Run your command again.
At C:\Windows\TEMP\tmp206027652026805712.ps1:7 char:1
+ wait-process -id $oopid -timeout 60 -WarningAction SilentlyContinue
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (System.Diagnostics.Process
(Idl
e):Process) [Wait-Process], ProcessCommandException
+ FullyQualifiedErrorId :
WaitOnIdleProcess,Microsoft.PowerShell.Commands.
WaitProcessCommand
===============================
command exit code: 0
The code above is part of a larger process that gets run on many services on Windows 2012 servers and Win 7 workstations. Sometimes though it fails and I don't know why. In this case, the correct service name is retrieved which can be seen in the command ouptut but the PID is 0, which can't possibly be correct as that's the system idle process's PID.
The parent software calling this PS script later shows that files in the HotKey install folder cannot be updated because, "(The process cannot access the file because it is being used by another process)", which makes sense because the HotKeyService service didn't stop correctly.
I ran the parent software again and it worked correctly on the same service.
My question is how could Get-WMIObject return the correct service name but then on the next step show a PID of zero? I can't figure this one out.
Thanks for the assistance.
KJ
When you see a Win32_Service instance with a ProcessId value of 0, it simply means that the service isn't running.
You'll find that:
(Get-WMiObject Win32_Service -Filter "Name ='HotKeyService'").State
is Stopped

Start-Process : Process with an Id of 5344 is not running

PS C:\> start regedit -ArgumentList '/S', 'D:\resources\hawk_config.reg' -Wait
Start-Process : Process with an Id of 5344 is not running.
At line:1 char:6
+ start <<<< regedit -ArgumentList '/S', 'D:\resources\hawk_config.reg'
+ CategoryInfo : NotSpecified: (:) [Start-Process], ArgumentException
+ FullyQualifiedErrorId : System.ArgumentException,Microsoft.PowerShell.Commands.StartProcessCommand
I can't figure out what it is. Any ideas?
Doesn't the /S parameter cause regedit to exit as soon as it's merged the .reg file? I suspect the error you are getting is because regedit has already exited before Start-Process has a chance to call Process.WaitForExit() on the process object. Take a look at the bowels of the error by running $error[0] | Format-List * right after the command. WaitForExit() will throw a SystemException if the process has already exited. I can't repro this on PowerShell v3. Perhaps they fixed an issue with this cmdlet.
As a workaround you could try:
$p = start-process regedit -ArgumentList '/S', 'D:\resources\hawk_config.reg' -passthru
$p.WaitForExit()
WaitForExit() will throw a SystemException if the process has already exited.
I get this same thing randomly in a PS script that uses start-process in a loop. never on the same iteration, sometimes never at all. this would explain that behavior perfectly. Random asynchronous timing of threads and processes.
I tried the suggested error message dump and it looks like it confirms the idea that the process is finishing before WaitForExit() gets to see it:
Start-Process : Cannot process request because the process (38152) has exited.
$result = start-process <<<< -filepath $compiler -argumentlist $argstr -nonewwindow -passthru -wait
CategoryInfo : NotSpecified: (:) [Start-Process], InvalidOperationException
+ FullyQualifiedErrorId : System.InvalidOperationException,Microsoft.PowerShell.Commands.StartProcessCommand