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?
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
}