Search code examples
powershellinvoke-command

Remote output from Get-SmbAccess


I have this code bit, I am trying to get to work in a script:

$computers = Get-ADComputer -Filter *  | Select-Object -ExpandProperty Name
$results = Invoke-Command -ComputerName $computers -ScriptBlock {Get-SmbShare | Get-SmbShareAccess}

I would like it to return the AccessRights as if was run locally - but this return numbers instead of text. Like AccessRight '0', '2' etc.

Name     AccountName                      AccessRight
----     -----------                      -----------
IPC$     BUILTIN\Administrators                     0
IPC$     BUILTIN\Backup Operators                   0
IPC$     NT AUTHORITY\INTERACTIVE                   0

How can I fix this?


Solution

  • Since 'AccessRight' is defined as a 'ScriptProperty', the friendly name is being calculate at access time. That is, PowerShell only looks it up when you access the property (e.g. when building the table output). Use Get-Member to see the definition:

    Get-SmbShare | Get-SmbShareAccess | Get-Member | Format-List *
    
    TypeName   : Microsoft.Management.Infrastructure.CimInstance#ROOT/Microsoft/Windows/Smb/MSFT_SmbShareAccessControlEntry
    Name       : AccessRight
    MemberType : ScriptProperty
    Definition : System.Object AccessRight {get=[Microsoft.PowerShell.Cmdletization.GeneratedTypes.SmbShare.ShareAccessRight] 
                 ($this.PSBase.CimInstanceProperties['AccessRight'].Value);}
    

    As the information needed to convert it is not loaded locally by default when making remote calls, PowerShell can only show you the raw integer value:

    TypeName   : Microsoft.Management.Infrastructure.CimInstance#ROOT/Microsoft/Windows/SMB/MSFT_SmbShareAccessControlEntry
    Name       : AccessRight
    MemberType : Property
    Definition : uint32 AccessRight {get;}
    

    You could write some code to convert it yourself (say as another calculated property), or a quick hack would be to run the SMB cmdlets locally before running them remotely to force the necessary definitions to be loaded:

    Get-SmbShare | Out-Null
    
    Invoke-Command -ComputerName 'RemoteServer' -ScriptBlock {
        Get-SmbShare | Get-SmbShareAccess
    }