Private/Add-InforcerPropertyAliases.ps1
|
function Add-InforcerPropertyAliases { <# .SYNOPSIS Adds PascalCase alias properties to API response objects (Private helper). .DESCRIPTION Adds PascalCase alias properties to API response objects (Private helper). Adds aliases only when the source property exists and the alias does not. See -ObjectType ValidateSet for supported types. .PARAMETER InputObject The PSObject to add aliases to (e.g. from API). .PARAMETER ObjectType Type of object for alias mapping. #> [CmdletBinding()] param( [Parameter(Mandatory = $true, ValueFromPipeline = $true)] [object]$InputObject, [Parameter(Mandatory = $true)] [ValidateSet('Tenant', 'Baseline', 'Policy', 'AlignmentScore', 'AlignmentDetail', 'AuditEvent', 'UserSummary', 'User', 'GroupSummary', 'Group', 'Role', 'Assessment', 'ReportType', 'ReportRun', 'ReportOutput')] [string]$ObjectType ) process { if ($null -eq $InputObject) { return } $obj = $InputObject function AddAliasIfExists { param([PSObject]$o, [string]$aliasName, [string]$sourceName) if ($null -eq $o) { return } $src = $o.PSObject.Properties[$sourceName] $al = $o.PSObject.Properties[$aliasName] if ($src -and -not $al) { $o.PSObject.Properties.Add([System.Management.Automation.PSAliasProperty]::new($aliasName, $sourceName)) } } switch ($ObjectType) { 'Tenant' { AddAliasIfExists $obj 'ClientTenantId' 'clientTenantId' AddAliasIfExists $obj 'MsTenantId' 'msTenantId' AddAliasIfExists $obj 'TenantFriendlyName' 'tenantFriendlyName' AddAliasIfExists $obj 'TenantDnsName' 'tenantDnsName' AddAliasIfExists $obj 'SecureScore' 'secureScore' AddAliasIfExists $obj 'IsBaseline' 'isBaseline' AddAliasIfExists $obj 'LastBackupTimestamp' 'lastBackupTimestamp' AddAliasIfExists $obj 'RecentChanges' 'recentChanges' AddAliasIfExists $obj 'PolicyDiff' 'policyDiff' # Licenses: replace array with comma-separated string (e.g. sku values or item ToString()) $licensesProp = $obj.PSObject.Properties['licenses'] if ($licensesProp -and $null -ne $licensesProp.Value) { $arr = @($licensesProp.Value) $parts = [System.Collections.Generic.List[string]]::new($arr.Count) foreach ($x in $arr) { if ($null -eq $x) { continue } $val = $null if ($x -is [PSObject] -and $x.PSObject.Properties['sku']) { $val = $x.PSObject.Properties['sku'].Value -as [string] } elseif ($x -is [PSObject] -and $x.PSObject.Properties['name']) { $val = $x.PSObject.Properties['name'].Value -as [string] } else { $val = $x.ToString().Trim() } if (-not [string]::IsNullOrWhiteSpace($val)) { [void]$parts.Add($val) } } $licensesStr = $parts -join ', ' $licensesProp.Value = $licensesStr } } 'Baseline' { AddAliasIfExists $obj 'BaselineClientTenantId' 'baselineClientTenantId' AddAliasIfExists $obj 'BaselineId' 'id' AddAliasIfExists $obj 'BaselineName' 'name' AddAliasIfExists $obj 'BaselineTenantFriendlyName' 'baselineTenantFriendlyName' AddAliasIfExists $obj 'BaselineTenantDnsName' 'baselineTenantDnsName' AddAliasIfExists $obj 'BaselineMsTenantId' 'baselineMsTenantId' AddAliasIfExists $obj 'AlignedThreshold' 'alignedThreshold' AddAliasIfExists $obj 'SemiAlignedThreshold' 'semiAlignedThreshold' $membersProp = $obj.PSObject.Properties['members'] if ($membersProp -and $membersProp.Value -is [object[]]) { foreach ($member in $membersProp.Value) { if ($member -is [PSObject]) { AddAliasIfExists $member 'ClientTenantId' 'clientTenantId' AddAliasIfExists $member 'MsTenantId' 'msTenantId' AddAliasIfExists $member 'TenantFriendlyName' 'tenantFriendlyName' AddAliasIfExists $member 'TenantDnsName' 'tenantDnsName' AddAliasIfExists $member 'SecureScore' 'secureScore' AddAliasIfExists $member 'IsBaseline' 'isBaseline' AddAliasIfExists $member 'LastBackupTimestamp' 'lastBackupTimestamp' AddAliasIfExists $member 'RecentChanges' 'recentChanges' } } } } 'Policy' { AddAliasIfExists $obj 'PolicyId' 'id' AddAliasIfExists $obj 'PolicyTypeId' 'policyTypeId' AddAliasIfExists $obj 'FriendlyName' 'friendlyName' AddAliasIfExists $obj 'ReadOnly' 'readOnly' AddAliasIfExists $obj 'Product' 'product' AddAliasIfExists $obj 'PrimaryGroup' 'primaryGroup' AddAliasIfExists $obj 'SecondaryGroup' 'secondaryGroup' AddAliasIfExists $obj 'Platform' 'platform' AddAliasIfExists $obj 'PolicyCategoryId' 'policyCategoryId' # PolicyName: always set from displayName, name, or friendlyName (in that order); fallback "Policy {id}" $policyNameVal = $obj.PSObject.Properties['displayName'].Value -as [string] if ([string]::IsNullOrWhiteSpace($policyNameVal)) { $policyNameVal = $obj.PSObject.Properties['name'].Value -as [string] } if ([string]::IsNullOrWhiteSpace($policyNameVal)) { $policyNameVal = $obj.PSObject.Properties['friendlyName'].Value -as [string] } if ([string]::IsNullOrWhiteSpace($policyNameVal)) { $idVal = $obj.PSObject.Properties['id'].Value $policyNameVal = "Policy $(if ($null -ne $idVal) { $idVal } else { 'Unknown' })" } $pnProp = $obj.PSObject.Properties['PolicyName'] if ($pnProp) { $pnProp.Value = $policyNameVal } else { $obj.PSObject.Properties.Add([System.Management.Automation.PSNoteProperty]::new('PolicyName', $policyNameVal)) } # Hide redundant name, displayName, friendlyName so only PolicyName is shown foreach ($hide in @('name', 'displayName', 'friendlyName')) { if ($obj.PSObject.Properties[$hide]) { $obj.PSObject.Properties.Remove($hide) } } # Add FriendlyName alias AFTER removing originals (PSObject.Properties is case-insensitive) if (-not $obj.PSObject.Properties['FriendlyName']) { $obj.PSObject.Properties.Add([System.Management.Automation.PSAliasProperty]::new('FriendlyName', 'PolicyName')) } } 'AlignmentScore' { AddAliasIfExists $obj 'TenantId' 'tenantId' AddAliasIfExists $obj 'TenantFriendlyName' 'tenantFriendlyName' AddAliasIfExists $obj 'Score' 'score' AddAliasIfExists $obj 'BaselineGroupId' 'baselineGroupId' AddAliasIfExists $obj 'BaselineGroupName' 'baselineGroupName' AddAliasIfExists $obj 'LastComparisonDateTime' 'lastComparisonDateTime' } 'AlignmentDetail' { # Top-level alignment properties AddAliasIfExists $obj 'AlignmentScore' 'alignmentScore' AddAliasIfExists $obj 'BaselineTenantId' 'baselineTenantId' AddAliasIfExists $obj 'SubjectTenantId' 'subjectTenantId' AddAliasIfExists $obj 'SubjectDataTimestamp' 'subjectDataTimestamp' AddAliasIfExists $obj 'BaselineDataTimestamp' 'baselineDataTimestamp' AddAliasIfExists $obj 'CompletedAt' 'completedAt' # Metrics $metricsProp = $obj.PSObject.Properties['metrics'] if ($metricsProp -and $null -ne $metricsProp.Value -and $metricsProp.Value -is [PSObject]) { $m = $metricsProp.Value AddAliasIfExists $m 'TotalPolicies' 'totalPolicies' AddAliasIfExists $m 'MatchedPolicies' 'matchedPolicies' AddAliasIfExists $m 'MatchedWithAcceptedDeviations' 'matchedWithAcceptedDeviations' AddAliasIfExists $m 'DeviatedPolicies' 'deviatedPolicies' AddAliasIfExists $m 'RecommendedPoliciesFromBaseline' 'recommendedPoliciesFromBaseline' AddAliasIfExists $m 'CustomerOnlyPolicies' 'customerOnlyPolicies' } # Per-policy aliases (matchedPolicies and deviatedUnaccepted arrays) $alignPropCached = $obj.PSObject.Properties['alignment'] if ($alignPropCached -and $null -ne $alignPropCached.Value) { $alignVal = $alignPropCached.Value } foreach ($arrayName in @('matchedPolicies', 'matchedWithAcceptedDeviations', 'deviatedUnaccepted', 'missingFromSubjectUnaccepted', 'additionalInSubjectUnaccepted')) { if ($null -eq $alignVal) { continue } $policyArrayProp = $alignVal.PSObject.Properties[$arrayName] if (-not $policyArrayProp -or $null -eq $policyArrayProp.Value) { continue } foreach ($policy in @($policyArrayProp.Value)) { if (-not ($policy -is [PSObject])) { continue } AddAliasIfExists $policy 'PolicyName' 'policyName' AddAliasIfExists $policy 'Product' 'product' AddAliasIfExists $policy 'PrimaryGroup' 'primaryGroup' AddAliasIfExists $policy 'SecondaryGroup' 'secondaryGroup' AddAliasIfExists $policy 'Platform' 'platform' AddAliasIfExists $policy 'PolicyTypeId' 'policyTypeId' AddAliasIfExists $policy 'InforcerPolicyTypeName' 'inforcerPolicyTypeName' AddAliasIfExists $policy 'PolicyCategoryId' 'policyCategoryId' AddAliasIfExists $policy 'IsDeviation' 'isDeviation' AddAliasIfExists $policy 'IsMissingFromSubject' 'isMissingFromSubject' AddAliasIfExists $policy 'IsAdditionalInSubject' 'isAdditionalInSubject' AddAliasIfExists $policy 'ReadOnly' 'readOnly' } } } 'AuditEvent' { AddAliasIfExists $obj 'CorrelationId' 'correlationId' AddAliasIfExists $obj 'ClientId' 'clientId' AddAliasIfExists $obj 'RelType' 'relType' AddAliasIfExists $obj 'RelId' 'relId' AddAliasIfExists $obj 'EventType' 'eventType' AddAliasIfExists $obj 'Message' 'message' AddAliasIfExists $obj 'Code' 'code' AddAliasIfExists $obj 'User' 'user' AddAliasIfExists $obj 'Timestamp' 'timestamp' # Flatten metadata onto the event so it works directly in the cmdlet output (no need to pipe .metadata) $meta = $obj.PSObject.Properties['metadata'].Value if ($null -ne $meta -and $meta -is [PSObject]) { $metaProps = $meta.PSObject.Properties # Only IPv4 and IPv6 (skip generic clientIp to avoid duplicating when same as clientIpv4) foreach ($pn in @('clientIpv4','clientIpv6')) { $noteName = $pn.Substring(0,1).ToUpper() + $pn.Substring(1) $p = $metaProps[$pn] if ($null -eq $p) { $p = $metaProps[$noteName] } if (-not $obj.PSObject.Properties[$noteName]) { $val = if ($p -and $null -ne $p.Value) { $p.Value } else { '' } $obj.PSObject.Properties.Add([System.Management.Automation.PSNoteProperty]::new($noteName, $val)) } } $nameLookup = $metaProps['nameLookup'].Value if ($null -ne $nameLookup) { $username = $null $displayName = $null if ($nameLookup -is [PSObject]) { foreach ($kp in $nameLookup.PSObject.Properties) { $k = $kp.Name; $v = $kp.Value # Only match user: prefixed keys (e.g. "user:username:763", "user:displayName:763") # Skip non-user keys like "alertRuleConfig:displayName:..." if ($k -like 'user:username:*') { $username = $v } if ($k -like 'user:displayName:*') { $displayName = $v } } } if ($username -and -not $obj.PSObject.Properties['UserName']) { $obj.PSObject.Properties.Add([System.Management.Automation.PSNoteProperty]::new('UserName', $username)) } if ($displayName -and -not $obj.PSObject.Properties['UserDisplayName']) { $obj.PSObject.Properties.Add([System.Management.Automation.PSNoteProperty]::new('UserDisplayName', $displayName)) } } } # Keep metadata on the object — Format.ps1xml controls default view. # Metadata contains event-type-specific data (e.g. alertRuleCreate has createAlertRuleConfigCommand) # accessible via $event.metadata or Select-Object *. } 'UserSummary' { AddAliasIfExists $obj 'Id' 'id' AddAliasIfExists $obj 'DisplayName' 'displayName' AddAliasIfExists $obj 'UserPrincipalName' 'userPrincipalName' AddAliasIfExists $obj 'UserType' 'userType' AddAliasIfExists $obj 'JobTitle' 'jobTitle' AddAliasIfExists $obj 'Department' 'department' AddAliasIfExists $obj 'Groups' 'groups' AddAliasIfExists $obj 'Roles' 'roles' AddAliasIfExists $obj 'AssignedLicenses' 'assignedLicenses' AddAliasIfExists $obj 'IsGlobalAdmin' 'isGlobalAdmin' AddAliasIfExists $obj 'IsAccountEnabled' 'isAccountEnabled' AddAliasIfExists $obj 'IsMfaRegistered' 'isMfaRegistered' AddAliasIfExists $obj 'IsMfaCapable' 'isMfaCapable' } 'User' { # Shared with UserSummary AddAliasIfExists $obj 'Id' 'id' AddAliasIfExists $obj 'DisplayName' 'displayName' AddAliasIfExists $obj 'UserPrincipalName' 'userPrincipalName' AddAliasIfExists $obj 'UserType' 'userType' AddAliasIfExists $obj 'JobTitle' 'jobTitle' AddAliasIfExists $obj 'Department' 'department' AddAliasIfExists $obj 'AssignedLicenses' 'assignedLicenses' AddAliasIfExists $obj 'IsGlobalAdmin' 'isGlobalAdmin' AddAliasIfExists $obj 'IsMfaRegistered' 'isMfaRegistered' AddAliasIfExists $obj 'IsMfaCapable' 'isMfaCapable' # Detail-only properties AddAliasIfExists $obj 'GivenName' 'givenName' AddAliasIfExists $obj 'Surname' 'surname' AddAliasIfExists $obj 'Mail' 'mail' AddAliasIfExists $obj 'MobilePhone' 'mobilePhone' AddAliasIfExists $obj 'BusinessPhones' 'businessPhones' AddAliasIfExists $obj 'OfficeLocation' 'officeLocation' AddAliasIfExists $obj 'StreetAddress' 'streetAddress' AddAliasIfExists $obj 'City' 'city' AddAliasIfExists $obj 'State' 'state' AddAliasIfExists $obj 'PostalCode' 'postalCode' AddAliasIfExists $obj 'Country' 'country' AddAliasIfExists $obj 'PreferredLanguage' 'preferredLanguage' AddAliasIfExists $obj 'AccountEnabled' 'accountEnabled' AddAliasIfExists $obj 'UsageLocation' 'usageLocation' AddAliasIfExists $obj 'CreatedDateTime' 'createdDateTime' AddAliasIfExists $obj 'LastPasswordChangeDateTime' 'lastPasswordChangeDateTime' AddAliasIfExists $obj 'LastSignInDateTime' 'lastSignInDateTime' AddAliasIfExists $obj 'CompanyName' 'companyName' AddAliasIfExists $obj 'EmployeeId' 'employeeId' AddAliasIfExists $obj 'EmployeeType' 'employeeType' AddAliasIfExists $obj 'EmployeeHireDate' 'employeeHireDate' AddAliasIfExists $obj 'MailNickname' 'mailNickname' AddAliasIfExists $obj 'PreferredDataLocation' 'preferredDataLocation' AddAliasIfExists $obj 'OnPremisesSyncEnabled' 'onPremisesSyncEnabled' AddAliasIfExists $obj 'OtherMails' 'otherMails' AddAliasIfExists $obj 'ProxyAddresses' 'proxyAddresses' AddAliasIfExists $obj 'CreationType' 'creationType' AddAliasIfExists $obj 'PasswordPolicies' 'passwordPolicies' AddAliasIfExists $obj 'SignInSessionsValidFromDateTime' 'signInSessionsValidFromDateTime' AddAliasIfExists $obj 'ImAddresses' 'imAddresses' AddAliasIfExists $obj 'LegalAgeGroupClassification' 'legalAgeGroupClassification' AddAliasIfExists $obj 'OnPremisesLastSyncDateTime' 'onPremisesLastSyncDateTime' AddAliasIfExists $obj 'OnPremisesDistinguishedName' 'onPremisesDistinguishedName' AddAliasIfExists $obj 'OnPremisesDomainName' 'onPremisesDomainName' AddAliasIfExists $obj 'OnPremisesImmutableId' 'onPremisesImmutableId' AddAliasIfExists $obj 'OnPremisesSecurityIdentifier' 'onPremisesSecurityIdentifier' AddAliasIfExists $obj 'OnPremisesSamAccountName' 'onPremisesSamAccountName' AddAliasIfExists $obj 'OnPremisesUserPrincipalName' 'onPremisesUserPrincipalName' AddAliasIfExists $obj 'Manager' 'manager' AddAliasIfExists $obj 'Groups' 'groups' AddAliasIfExists $obj 'Devices' 'devices' AddAliasIfExists $obj 'Roles' 'roles' AddAliasIfExists $obj 'AppRoleAssignments' 'appRoleAssignments' AddAliasIfExists $obj 'IsCloudOnly' 'isCloudOnly' AddAliasIfExists $obj 'IsHybrid' 'isHybrid' AddAliasIfExists $obj 'IsAllDevicesCompliant' 'isAllDevicesCompliant' AddAliasIfExists $obj 'RiskState' 'riskState' AddAliasIfExists $obj 'RiskDetail' 'riskDetail' AddAliasIfExists $obj 'RiskLevel' 'riskLevel' } 'GroupSummary' { AddAliasIfExists $obj 'Id' 'id' AddAliasIfExists $obj 'DisplayName' 'displayName' AddAliasIfExists $obj 'Description' 'description' AddAliasIfExists $obj 'Mail' 'mail' AddAliasIfExists $obj 'Visibility' 'visibility' AddAliasIfExists $obj 'GroupTypes' 'groupTypes' } 'Group' { AddAliasIfExists $obj 'Id' 'id' AddAliasIfExists $obj 'DisplayName' 'displayName' AddAliasIfExists $obj 'Description' 'description' AddAliasIfExists $obj 'Mail' 'mail' AddAliasIfExists $obj 'MailNickname' 'mailNickname' AddAliasIfExists $obj 'Visibility' 'visibility' AddAliasIfExists $obj 'MembershipRule' 'membershipRule' AddAliasIfExists $obj 'GroupTypes' 'groupTypes' AddAliasIfExists $obj 'CreatedDateTime' 'createdDateTime' AddAliasIfExists $obj 'MailEnabled' 'mailEnabled' AddAliasIfExists $obj 'OnPremisesSyncEnabled' 'onPremisesSyncEnabled' AddAliasIfExists $obj 'Members' 'members' } 'Role' { AddAliasIfExists $obj 'Id' 'id' AddAliasIfExists $obj 'TemplateId' 'templateId' AddAliasIfExists $obj 'DisplayName' 'displayName' AddAliasIfExists $obj 'Description' 'description' AddAliasIfExists $obj 'IsBuiltIn' 'isBuiltIn' AddAliasIfExists $obj 'IsEnabled' 'isEnabled' AddAliasIfExists $obj 'IsPrivileged' 'isPrivileged' } 'Assessment' { AddAliasIfExists $obj 'Id' 'id' AddAliasIfExists $obj 'Name' 'name' AddAliasIfExists $obj 'Description' 'description' AddAliasIfExists $obj 'AssessmentType' 'assessmentType' AddAliasIfExists $obj 'LastUpdated' 'lastUpdated' AddAliasIfExists $obj 'Created' 'created' # Keep raw 'tags' shape intact (array OR comma-separated string from the API); # downstream filters (e.g. Get-InforcerReportType -Tag) rely on the raw shape, # and the Format.ps1xml view joins for display. AddAliasIfExists $obj 'Tags' 'tags' } 'ReportType' { AddAliasIfExists $obj 'Key' 'key' AddAliasIfExists $obj 'Name' 'name' AddAliasIfExists $obj 'Description' 'description' AddAliasIfExists $obj 'Collatable' 'collatable' # API uses 'supportedOutputFormats' (confirmed against api-uk.inforcer.com beta). AddAliasIfExists $obj 'SupportedOutputFormats' 'supportedOutputFormats' AddAliasIfExists $obj 'OutputFormats' 'supportedOutputFormats' AddAliasIfExists $obj 'RequiredParameters' 'requiredParameters' AddAliasIfExists $obj 'Parameters' 'requiredParameters' # Keep raw 'tags' shape intact (array OR comma-separated string from the API); # downstream filters (e.g. Get-InforcerReportType -Tag) rely on the raw shape, # and the Format.ps1xml view joins for display. AddAliasIfExists $obj 'Tags' 'tags' } 'ReportRun' { # API uses 'runId' (confirmed). Each run can batch multiple report types # and output formats — hence the plurals. Field set verified against api-uk.inforcer.com. AddAliasIfExists $obj 'RunId' 'runId' AddAliasIfExists $obj 'Id' 'runId' AddAliasIfExists $obj 'Status' 'status' AddAliasIfExists $obj 'ReportTypes' 'reportTypes' AddAliasIfExists $obj 'OutputFormats' 'outputFormats' AddAliasIfExists $obj 'TriggeredByType' 'triggeredByType' AddAliasIfExists $obj 'CreatedAt' 'createdAt' AddAliasIfExists $obj 'StartedAt' 'startedAt' AddAliasIfExists $obj 'CompletedAt' 'completedAt' AddAliasIfExists $obj 'OutputCount' 'outputCount' } 'ReportOutput' { # Output record uses: id (output id), reportType, tenantId, format, sizeBytes AddAliasIfExists $obj 'OutputId' 'id' AddAliasIfExists $obj 'Id' 'id' AddAliasIfExists $obj 'RunId' 'runId' AddAliasIfExists $obj 'TenantId' 'tenantId' AddAliasIfExists $obj 'ReportType' 'reportType' AddAliasIfExists $obj 'OutputFormat' 'format' AddAliasIfExists $obj 'FileSize' 'sizeBytes' } } $obj } } |