Not getting all data with Invoke-Command

I am trying to query our NANO 2016 servers, running from a Win2012R2 server with PS4 - maybe that’s where the problem is, but here it goes:

When getting everything back from Get-PhysicalDisk (without selecting any properties in the Invoke-Command) I am not getting the correct properties out:

$job = Invoke-Command -ComputerName HVC-C02A -ScriptBlock {
    Get-PhysicalDisk 
}

$job | select -first 1 | select OperationalStatus

Output:

OperationalStatus                                                                                                                                                                                                                                                                                                           
-----------------                                                                                                                                                                                                                                                                                                           
{2}                 

Get-Member:

PS C:\Windows\system32> $job | select -first 1 | select OperationalStatus | Get-Member


   TypeName: Selected.Microsoft.Management.Infrastructure.CimInstance

Name              MemberType   Definition                                       
----              ----------   ----------                                       
Equals            Method       bool Equals(System.Object obj)                   
GetHashCode       Method       int GetHashCode()                                
GetType           Method       type GetType()                                   
ToString          Method       string ToString()                                
OperationalStatus NoteProperty System.UInt16[] OperationalStatus=System.UInt16[]

Howevery, if I am selecting one or few properties in the Invoke-Command I am getting the datatypes that I am expecting:

$job2 = Invoke-Command -ComputerName HVC-C02A -ScriptBlock {
    Get-PhysicalDisk | Select OperationalStatus 
}

$job2 | select -First 1

Output:

OperationalStatus                                                                                         PSComputerName                                                                                            RunspaceId                                                                                              
-----------------                                                                                         --------------                                                                                            ----------                                                                                              
OK                                                                                                        HVC-C02A                                                                                                  48374846-56fa-44f9-ad9a-abb8d6f481eb                                                                    

Get-Member:

PS C:\Windows\system32> $job2 | select -First 1 | Get-Member


   TypeName: Selected.System.Management.Automation.PSCustomObject

Name               MemberType   Definition                                                 
----               ----------   ----------                                                 
Equals             Method       bool Equals(System.Object obj)                             
GetHashCode        Method       int GetHashCode()                                          
GetType            Method       type GetType()                                             
ToString           Method       string ToString()                                          
OperationalStatus  NoteProperty System.String OperationalStatus=OK                         
PSComputerName     NoteProperty System.String PSComputerName=HVC-C02A                      
PSShowComputerName NoteProperty System.Boolean PSShowComputerName=True                     
RunspaceId         NoteProperty System.Guid RunspaceId=48374846-56fa-44f9-ad9a-abb8d6f481eb

Edit: I also tried from a Win 2016 Datacenter (with GUI) and got the same result.

First thing I would do is enter the remoting session to the nano server. Run get-PhysicalDisk and see what you get

Hi Richard, sorry for not clearing that out in my first post. I did that and I get the same result as the second output (the correct way).
So it is related to Invoke-Command.

Best regards
Stig

The underlying status is probably an integer (much like Status on Get-Service), and PowerShell is doing some translation. By the time the object goes through serialization and deserialization in Remoting, your local computer doesn’t “know” to do the translation, so you’re just getting the raw, underlying value. When you do the Select remotely, then it’s the remote machine doing the translation - before the serialization, so it still “knows” to do it.

Hi Don, you are absolutely right!

If I use select * then it works:

$job = Invoke-Command -ComputerName HVC-C02A -ScriptBlock {
    Get-PhysicalDisk | select *
}

That then gives me the correct type for OperationalStatus and gives “OK” instead of {2}.

Funny it works this way though… So one should use select * if they are interesting in getting all the properties and their correct datatypes - when using Invoke-Command.

Big thanks to you.

The OperationalStatus property is an array

PS> (Get-CimClass -Namespace root/microsoft/windows/storage -ClassName MSFT_PhysicalDisk).CimClassProperties | where Name -eq 'OperationalStatus'


Name               : OperationalStatus
Value              :
CimType            : UInt16Array
Flags              : Property, ReadOnly, NullValue
Qualifiers         : {read, ValueMap}
ReferenceClassName :

If you dig a bit further

PS> (Get-PhysicalDisk | gm | where Name -eq 'OperationalStatus').Definition
System.Object OperationalStatus {get=$_status = @();
          foreach ( $status in $this.psBase.CimInstanceProperties["OperationalStatus"].Value )
          {
            switch ( $status )
            {
              1 { $_status += "Other" }
              2 { $_status += "OK" }
              3 { $_status += "Degraded" }
              4 { $_status += "Stressed" }
              5 { $_status += "Predictive Failure" }
              6 { $_status += "Error" }
              7 { $_status += "Non-Recoverable Error" }
              8 { $_status += "Starting" }
              9 { $_status += "Stopping" }
              10 { $_status += "Stopped" }
              11 { $_status += "In Service" }
              12 { $_status += "No Contact" }
              13 { $_status += "Lost Communication" }
              14 { $_status += "Aborted" }
              15 { $_status += "Dormant" }
              16 { $_status += "Supporting Entity in Error" }
              17 { $_status += "Completed" }
              18 { $_status += "Power Mode" }
              19 { $_status += "Relocating" }
              53252 { $_status += "Failed Media" }
              53253 { $_status += "Split" }
              53254 { $_status += "Stale Metadata" }
              53255 { $_status += "IO Error" }
              53256 { $_status += "Unrecognized Metadata" }
              53269 { $_status += "Removing From Pool" }
              53270 { $_status += "In Maintenance Mode" }
              53271 { $_status += "Updating Firmware" }
              53272 { $_status += "Device Hardware Error" }
              53273 { $_status += "Not Usable" }
              53274 { $_status += "Transient Error" }
              53276 { $_status += "Starting Maintenance Mode"}
              53277 { $_status += "Stopping Maintenance Mode"}
              Default { "Unknown" }
            }
          }
          $_status;;}

What happens if you create a CIM session to the nano server and run
$cs = New-CimSession -computername HVC-C02A
Get-PhysicalDisk -CimSession $cs

I’ve run some tests on this from a Windows 2016 server going to a Nano server

First I repeated the initial script

$job = Invoke-Command -ComputerName W16HV01 -ScriptBlock {
    Get-PhysicalDisk 
}
$job | select -first 1 | select OperationalStatus

OperationalStatus
-----------------
{2}

And got the same results.

Then tested a script block in same scenario. This is to see everything that is returned

$sb = {
    Get-PhysicalDisk 
}
Invoke-Command -ComputerName W16HV01 -ScriptBlock $sb


ClassName                        : MSFT_PhysicalDisk
PSComputerName                   : W16HV01
RunspaceId                       : ead58759-1957-4d2b-97a6-facdd3bb12cc
ObjectId                         : {1}\\W16HV01\root/Microsoft/Windows/Storage/
                                   Providers_v2\SPACES_PhysicalDisk.ObjectId="{
                                   58d6ee13-a3df-11e6-bbb0-806e6f6e6963}:PD:{8a
                                   4a1916-e842-d36e-67b9-973488c51a7a}"
PassThroughClass                 : 
PassThroughIds                   : 
PassThroughNamespace             : 
PassThroughServer                : 
UniqueId                         : 60022480B03EB44066A35B8D6963D320
Description                      : 
FriendlyName                     : Msft Virtual Disk
HealthStatus                     : 0
Manufacturer                     : Msft
Model                            : Virtual Disk
OperationalDetails               : 
OperationalStatus                : {2}
PhysicalLocation                 : Integrated : Adapter 0 : Port 0 : Target 0 
                                   : LUN 0
SerialNumber                     : 
AdapterSerialNumber              : 
AllocatedSize                    : 10737418240
BusType                          : 10
CannotPoolReason                 : {7}
CanPool                          : False
DeviceId                         : 0
EnclosureNumber                  : 
FirmwareVersion                  : 1.0
IsIndicationEnabled              : 
IsPartial                        : True
LogicalSectorSize                : 512
MediaType                        : 0
OtherCannotPoolReasonDescription : 
PartNumber                       : 
PhysicalSectorSize               : 4096
Size                             : 10737418240
SlotNumber                       : 
SoftwareVersion                  : 
SpindleSpeed                     : 4294967295
SupportedUsages                  : {1, 2, 3, 4...}
UniqueIdFormat                   : 3
Usage                            : 1
VirtualDiskFootprint             : 0

Got the same results

next try a remoting session

$sb = {
    Get-PhysicalDisk 
}
$s = New-PSSession -ComputerName W16HV01
Invoke-Command -Session $s -ScriptBlock $sb
Remove-PSSession $s

ClassName                        : MSFT_PhysicalDisk
PSComputerName                   : W16HV01
RunspaceId                       : 0afd86d2-fdfb-4df5-90cd-e820a0624ef5
ObjectId                         : {1}\\W16HV01\root/Microsoft/Windows/Storage/
                                   Providers_v2\SPACES_PhysicalDisk.ObjectId="{
                                   58d6ee13-a3df-11e6-bbb0-806e6f6e6963}:PD:{8a
                                   4a1916-e842-d36e-67b9-973488c51a7a}"
PassThroughClass                 : 
PassThroughIds                   : 
PassThroughNamespace             : 
PassThroughServer                : 
UniqueId                         : 60022480B03EB44066A35B8D6963D320
Description                      : 
FriendlyName                     : Msft Virtual Disk
HealthStatus                     : 0
Manufacturer                     : Msft
Model                            : Virtual Disk
OperationalDetails               : 
OperationalStatus                : {2}
PhysicalLocation                 : Integrated : Adapter 0 : Port 0 : Target 0 
                                   : LUN 0
SerialNumber                     : 
AdapterSerialNumber              : 
AllocatedSize                    : 10737418240
BusType                          : 10
CannotPoolReason                 : {7}
CanPool                          : False
DeviceId                         : 0
EnclosureNumber                  : 
FirmwareVersion                  : 1.0
IsIndicationEnabled              : 
IsPartial                        : True
LogicalSectorSize                : 512
MediaType                        : 0
OtherCannotPoolReasonDescription : 
PartNumber                       : 
PhysicalSectorSize               : 4096
Size                             : 10737418240
SlotNumber                       : 
SoftwareVersion                  : 
SpindleSpeed                     : 4294967295
SupportedUsages                  : {1, 2, 3, 4...}
UniqueIdFormat                   : 3
Usage                            : 1
VirtualDiskFootprint             : 0

same results

Try an interactive remoting session

PS C:\Scripts> Enter-PSSession -ComputerName W16HV01
[W16HV01]: PS C:\Users\Richard\Documents> get-physicaldisk

FriendlyName      SerialNumber CanPool OperationalStatus HealthStatus Usage    
------------      ------------ ------- ----------------- ------------ -----    
Msft Virtual Disk              False   OK                Healthy      Auto-S...

That gives the expected result

Now try a CIM session

$cs = New-CimSession -ComputerName W16HV01
Get-PhysicalDisk -CimSession $cs
Remove-CimSession $cs

FriendlyName      SerialNumber CanPool OperationalStatus HealthStatus Usage        Size
------------      ------------ ------- ----------------- ------------ -----        ----
Msft Virtual Disk              False   OK                Healthy      Auto-Select 10 GB

That work as well

Last test is to try PowerShell Direct from the Hyper-V host which is Windows 10

PS> $cred = Get-Credential "W16HV01\Administrator"
$s = New-PSSession -VMName W16HV01 -Credential $cred
Invoke-Command -Session $s -ScriptBlock {get-PhysicalDisk}
Remove-PSSession $s

ClassName                        : MSFT_PhysicalDisk
PSComputerName                   : W16HV01
RunspaceId                       : 2e29e8d0-07ad-482b-b466-9e37c8fc4b5d
ObjectId                         : {1}\\W16HV01\root/Microsoft/Windows/Storage/Providers_v2\SPACES_PhysicalDisk.ObjectId="{58d6ee13-a3df-11e6-bbb0-
                                   806e6f6e6963}:PD:{8a4a1916-e842-d36e-67b9-973488c51a7a}"
PassThroughClass                 : 
PassThroughIds                   : 
PassThroughNamespace             : 
PassThroughServer                : 
UniqueId                         : 60022480B03EB44066A35B8D6963D320
Description                      : 
FriendlyName                     : Msft Virtual Disk
HealthStatus                     : 0
Manufacturer                     : Msft
Model                            : Virtual Disk
OperationalDetails               : 
OperationalStatus                : {2}
PhysicalLocation                 : Integrated : Adapter 0 : Port 0 : Target 0 : LUN 0
SerialNumber                     : 
AdapterSerialNumber              : 
AllocatedSize                    : 10737418240
BusType                          : 10
CannotPoolReason                 : {7}
CanPool                          : False
DeviceId                         : 0
EnclosureNumber                  : 
FirmwareVersion                  : 1.0
IsIndicationEnabled              : 
IsPartial                        : True
LogicalSectorSize                : 512
MediaType                        : 0
OtherCannotPoolReasonDescription : 
PartNumber                       : 
PhysicalSectorSize               : 4096
Size                             : 10737418240
SlotNumber                       : 
SoftwareVersion                  : 
SpindleSpeed                     : 4294967295
SupportedUsages                  : {1, 2, 3, 4...}
UniqueIdFormat                   : 3
Usage                            : 1
VirtualDiskFootprint             : 0

That gives original result

Last test was to try against Windows 2016 remote machine (server core)

PS C:\Scripts> Invoke-Command -ScriptBlock {Get-PhysicalDisk} -ComputerName W16DC01



FriendlyName      SerialNumber CanPool OperationalStatus HealthStatus Usage         Size PSComputerName
------------      ------------ ------- ----------------- ------------ -----         ---- --------------
Msft Virtual Disk              False   OK                Healthy      Auto-Select 127 GB W16DC01       

which works OK

Looks like there could be an issue with remoting CIM based cmdlets to Nano server

Wow, Richard! That’s awesome debugging. Thank you for the effort and showing me. I learned alot from that post. Now knowing how to find the answer myself next time :slight_smile:

Big thanks

Best regards
Stig Sörnsen