How to catch Access denied from Get-CimInstance in remote session?

I am trying to determine local path for given netshare on remote computer. For admin users all runs as expected, for non admin users the script terminates, because I can not figure out how to catch the exception.

Code (much simplified):

$credential = Get-credential $env:USERNAME
$session = New-PSSession -ComputerName tfs-build1 -EnableNetworkAccess -Credential $credential -Authentication Credssp
Invoke-Command -Session $session { 
$shareName = 'Projects'
# ... snip

try {
    $sharePath = (Get-CimInstance -ClassName Win32_Share -Filter "name like `"$shareName`"").Path 
}
catch {
    # can not get here
    Write-Warning $_
}

# ... snip
}

The error I get:

Access is denied.
+ CategoryInfo : PermissionDenied: (:) [Get-CimInstance], CimException
+ FullyQualifiedErrorId : HRESULT 0x80070005,Microsoft.Management.Infrastructure.CimCmdlets.GetCimInstanceCommand
+ PSComputerName : tfs-build1

$PSVersionTable from the target server:

Name                           Value                                                                                                                      
----                           -----                                                                                                                      
PSRemotingProtocolVersion      2.3                                                                                                                        
BuildVersion                   10.0.14409.1018                                                                                                            
PSVersion                      5.1.14409.1018                                                                                                             
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}                                                                                                    
PSEdition                      Desktop                                                                                                                    
CLRVersion                     4.0.30319.42000                                                                                                            
WSManStackVersion              3.0                                                                                                                        
SerializationVersion           1.1.0.1   

What I tried (and did not work):

  • try {} catch {}
  • setting $ErrorActionPreference to Continue, Stop
  • using parameter ErrorAction with values SilentlyContinue, Continue, Stop
  • trap {}
I have a workaround (see below), but I would really like to do this the PowerShell way...

Workaround:

if ((&"net" share "$shareName" | Select-Object -Skip 1 -First 1) -match "^.+\s+(?'path'.+)$")
{
    $sharePath = $Matches['path']
}

Thanks for any ideas.

All things I tried to catch the error are now working. Seems like server restart was needed.

Edit:

Or not. I thought I can simulate the conditions by adding parameter -ComputerName to the Get-CimInstance command with a computer I am not admin on…

If I understand correctly, your script opens a remote session and then performs a task, but depending on the user’s credentials that task may fail on the remote target. The failure causes a terminating error for the remote session and results in the entire script terminating. You want the script to handle the remote session error, display a warning on localhost, and continue executing.

First off, your Write-Warning at line 12 does not work because it is inside the remote session. If it produces a warning output, that output will only be shown on the remote target and not localhost.

This is effectively unsolvable. The remote session does not actively share information with the local session that initiated it. However, it is possible to capture the error using the method recommended here: https://stackoverflow.com/questions/12600921/handle-errors-in-scriptblock-in-invoke-command-cmdlet and then use that to create a warning message at localhost after the remote session closes.

What exactly happens if you apply -ErrorAction Continue to Get-CimInstance? Does your script terminate because of the Get-CimInstance error, or does it terminate after because it does not have the expected output of the remote session?

Yes. The Warning is not essential (neither for script or user). I need to catch the error and handle the situation gracefully.

I can see the warning.

Invoke-Command -Session $session { 
# ... snip 
$shareName = 'Projects'

try {
$ErrorActionPreference = 'Stop'
$share = Get-CimInstance -ClassName Win32_Share -ErrorAction Stop -Filter "name like `"$shareName`""
$sharePath = $share.Path 
}
catch {
# can not get here
Write-Warning $_
}
Write-Host OK -ForegroundColor Green 

# ... snip
}

results in

WARNING: Access is denied.
OK

After change of ErrorAction to Continue I get:

Access is denied.
+ CategoryInfo : PermissionDenied: (:) [Get-CimInstance], CimException
+ FullyQualifiedErrorId : HRESULT 0x80070005,Microsoft.Management.Infrastructure.CimCmdlets.GetCimInstanceCommand
+ PSComputerName : tfs-build1

OK

But for the affected users the script terminates at Get-CimInstance:

Access is denied.
+ CategoryInfo : PermissionDenied: (:) [Get-CimInstance], CimException
+ FullyQualifiedErrorId : HRESULT 0x80070005,Microsoft.Management.Infrastructure.CimCmdlets.GetCimInstanceCommand
+ PSComputerName : tfs-build1

the only thing i can say is that the error HRESULT 0x80070005 seems to be related to the permission the user (don’t) have to access,
i faced the same error with Get-WmiObject, which worked with administrator rights but didn’t work when issueing -AsJob parameter (again with Administrator rights)

I my research trying to figure this error out and eventually fixing it I only discovered how to give the right permissions to users that
use remoting, for me it didn’t work because Administrator user has permissions already.

If you didn’t check yet, you can search for DCOM and WMI permission related to the user you are using:
Running (WinKey+R) dcomcnfg you can verify the permissions that every user have

I only found few blurry information for my problem, but i hope this will be usefull to you

As it turned out, there is only one affected user, and he (for whatever reason) sees an older version of the script.

Thanks for your time.