2

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?

Bubblies
  • 23
  • 4
  • the SMB cmdlets are not available with ps5.1 on win7, so this is a guess ... that looks like an _enum_. if so, you will likely need to derive the text value for that at the source - perhaps with `.ToString()`? – Lee_Dailey Sep 25 '19 at 14:29

2 Answers2

2

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
}
boxdog
  • 7,894
  • 2
  • 18
  • 27
0

Why don't you try:

$computers = (Get-ADComputer -Filter *).Name
$result = Get-SmbShare -CimSession $computers | Get-SmbShareAccess | Select-Object -Property Name, AccountName, AccessControlType, AccessRight, PSComputerName

Note: Select-Object is optional. I have used it to show PSComputerName Property, so to identify, which computer provides the output

enter image description here

Hope it helps!

Ivan Mirchev
  • 829
  • 5
  • 8