Home > Software engineering >  Powershell Attempting to Group object by a nested value
Powershell Attempting to Group object by a nested value

Time:04-25

I have a json file i am converting to an object called $sets and i am trying to group those objects by a value that is nest in each object. each object looks like this

{
    "$type": "DeviceIos",
    "ActivationLockBypassCode": "example bypass code",
    "ActivationLockBypassStatus": "CodeValid",
    "AgentVersion": null,
    "Memory": {
      "$type": "Memory",
      "AvailableExternalStorage": null,
      "AvailableMemory": null,
      "AvailableSDCardStorage": null,
      "AvailableStorage": 24552280064,
      "TotalExternalStorage": null,
      "TotalMemory": null,
      "TotalSDCardStorage": null,
      "TotalStorage": 34359738368
    },
    "BatteryStatus": 58,
    "BuildVersion": "19C56",
    "CarrierSettingsVersion": null,
    "CellularCarrier": null,
    "CellularTechnology": "None",
    "CurrentMCC": null,
    "CurrentMNC": null,
    "DataRoamingEnabled": false,
    "DeviceTerms": null,
    "DeviceUserInfo": null,
    "MultiUserDeviceInfo": null,
    "ExchangeBlocked": false,
    "ExchangeAccessRequest": "None",
    "ExchangeStatus": "Accepted",
    "FirmwareVersion": null,
    "HardwareEncryptionCaps": 3,
    "HardwareEncryption": "Both",
    "ICCID": null,
    "IMEI_MEID_ESN": null,
    "InRoaming": false,
    "Ipv6": null,
    "IsActivationLockEnabled": false,
    "IsAgentCompatible": true,
    "IsAgentless": true,
    "IsDeviceLocatorServiceEnabled": false,
    "IsDoNotDisturbInEffect": false,
    "IsEncrypted": true,
    "IsEnrolled": true,
    "IsITunesStoreAccountActive": false,
    "IsMDMLostModeEnabled": false,
    "IsOSSecure": true,
    "IsPersonalHotspotEnabled": null,
    "IsSupervised": true,
    "ItunesIdHash": null,
    "LastCheckInTime": null,
    "LastAgentConnectTime": null,
    "LastAgentDisconnectTime": null,
    "LastLoggedOnUser": null,
    "ManagedAppleId": null,
    "LastStatusUpdate": "2022-04-13T14:07:11.417Z",
    "ManufacturerSerialNumber": "example serial number",
    "ModelNumber": "MVHW2LL",
    "ModemFirmwareVersion": null,
    "NetworkConnectionType": "Unknown",
    "PasscodeEnabled": true,
    "PasscodeStatus": "DataProtectionEnabled",
    "PersonalizedName": "examplename",
    "PhoneNumber": null,
    "ProductName": "iPod9,1",
    "SIMCarrierNetwork": null,
    "SubscriberMCC": null,
    "SubscriberMNC": null,
    "SubscriberNumber": null,
    "UserIdHash": null,
    "VoiceRoamingEnabled": false,
    "ManagementProfileUpdateTime": "2022-03-24T19:01:02.193Z",
    "ManagementProfileSigningCertificateExpiry": "2045-01-27T00:00:00Z",
    "MDMClientCertificateHash": "example hash",
    "AppleBusinessManagerUserId": 0,
    "ExchangeOnlineEmailAccess": [],
    "Kind": "Ios",
    "CompliancePolicyStatus": "Compliant",
    "ComplianceStatus": true,
    "ComplianceItems": [
      {
        "$type": "ComplianceItem",
        "ComplianceType": "IsSecured",
        "ComplianceValue": true
      },
      {
        "$type": "ComplianceItem",
        "ComplianceType": "IsDeviceAdmin",
        "ComplianceValue": null
      },
      {
        "$type": "ComplianceItem",
        "ComplianceType": "NotWiped",
        "ComplianceValue": true
      },
      {
        "$type": "ComplianceItem",
        "ComplianceType": "IsEnabled",
        "ComplianceValue": true
      },
      {
        "$type": "ComplianceItem",
        "ComplianceType": "IsEnrolled",
        "ComplianceValue": true
      }
    ],
    "DeviceId": "example device id",
    "DeviceName": "example device name",
    "EnrollmentType": "Device",
    "EnrollmentTime": "2022-03-24T19:01:02.107Z",
    "Family": "Apple",
    "HostName": null,
    "IsAgentOnline": false,
    "CustomAttributes": [
      {
        "$type": "DeviceCustomAttribute",
        "Name": "Account_Name",
        "Value": "example account name",
        "DataType": "Text"
      },
      {
        "$type": "DeviceCustomAttribute",
        "Name": "Account_Number",
        "Value": "0001",
        "DataType": "Text"
      },
      {
        "$type": "DeviceCustomAttribute",
        "Name": "example name",
        "Value": "True",
        "DataType": "Boolean"
      },
      {
        "$type": "DeviceCustomAttribute",
        "Name": "example wave",
        "Value": "example value",
        "DataType": "Enumerator"
      }
    ],
    "MACAddress": "example",
    "BluetoothMAC": "example",
    "WifiMAC": "example",
    "Manufacturer": "Apple",
    "Mode": "Active",
    "Model": "iPod",
    "OSVersion": "exmaple osversion",
    "Path": "example path",
    "Platform": "platformname",
    "ServerName": null
  }

there are many object similar to this one they vary with different values but i would like to group them by the value of account_number under customattributes as these are the unique accounts. from what i understand from reading other posts you should be able to use a calculated property to do this but i cannot for the life of me figure how to do so. i have tried

$sets | Select-Object Account_Number, @{Name = 'Account_Number'; Expression = { $_ | Select-Object -ExpandProperty CustomAttributes | Where-Object { Name -eq "Account_Number" } | Select-Object -Property Value } } | Group-Object -Property Account_Number

when i try i get the message back

The property cannot be processed because the property "Account_Number" already exists.

i believe i have a fair grasp on grouping objects as i can do this fairly easy by any property at the first level IE i can do this easily by say BatteryStatus or BuildVersion but what i do not seem to grasp is how to select the right value from the object custom attributes. the main thing i have been looking at the seems closest that i can find to what i want to do is this entry PowerShell select and group by nested field trying to glean my own answer from the answer provided by johnlbevan

CodePudding user response:

Given the CustomAttributes nested object:

$type                 Name           Value                DataType
-----                 ----           -----                --------
DeviceCustomAttribute Account_Name   example account name Text
DeviceCustomAttribute Account_Number 0001                 Text
DeviceCustomAttribute example name   True                 Boolean
DeviceCustomAttribute example wave   example value        Enumerator

And breaking the problem in small pieces, you can get the Value of the Value property of the object where the Name property is equal to Account_Number with the following expression (using the Json posted in question as example):

$json.CustomAttributes.where{ $_.Name -eq 'Account_Number' }.Value # => 0001

In that sense, assuming you have an array of these objects as the one posted, you can group them using the same expression with Group-Object:

$json | Group-Object { $_.CustomAttributes.where{ $_.Name -eq 'Account_Number' }.Value }

As example, I have recreated 6 objects and modified some of these Values, the result is:

Count Name                      Group
----- ----                      -----
    4 0001                      {@{$type=DeviceIos; ActivationLockBypassCode=example....
    1 0002                      {@{$type=DeviceIos; ActivationLockBypassCode=example....
    1 0003                      {@{$type=DeviceIos; ActivationLockBypassCode=example....
  • Related