question

bernardmwanza-0900 avatar image
0 Votes"
bernardmwanza-0900 asked sikumars answered

How to convert Conditional Access "system.collections" values into friendly name upon running Get-AzureADMSConditionalAccessPolicy

I'm currently working on PowerShell script to retrieve Conditional access policies configurations. The information is required in a csv file to help management with auditing requests. As of current upon running Get-AzureADMSConditionalAccessPolicy cmdlet, the only data that i can grab and save to a csv file is: Id, display name and state. Conditions and controls comes in an obfuscated format of "system.collections" which cannot be understood.

 PS C:\Windows\system32> Get-AzureADMSConditionalAccessPolicy
    
    
 Id              : a77d724e-b9f9-452d-b1f0-d041142413a0
 DisplayName     : Block_Office365_Apps_Access_In_Android_Devices
 State           : enabled
 Conditions      : class ConditionalAccessConditionSet {
                     Applications: class ConditionalAccessApplicationCondition {
                     IncludeApplications: System.Collections.Generic.List`1[System.String]
                     ExcludeApplications: System.Collections.Generic.List`1[System.String]
                     IncludeUserActions: System.Collections.Generic.List`1[System.String]
                     IncludeProtectionLevels:
                   }
    
                     Users: class ConditionalAccessUserCondition {
                     IncludeUsers: System.Collections.Generic.List`1[System.String]
                     ExcludeUsers: System.Collections.Generic.List`1[System.String]
                     IncludeGroups: System.Collections.Generic.List`1[System.String]
                     ExcludeGroups: System.Collections.Generic.List`1[System.String]
                     IncludeRoles: System.Collections.Generic.List`1[System.String]
                     ExcludeRoles: System.Collections.Generic.List`1[System.String]
                   }
    
                     Platforms: class ConditionalAccessPlatformCondition {
                     IncludePlatforms: System.Collections.Generic.List`1[Microsoft.Open.MSGraph.Model.ConditionalAccessDevicePlatforms]
                     ExcludePlatforms: System.Collections.Generic.List`1[Microsoft.Open.MSGraph.Model.ConditionalAccessDevicePlatforms]
                   }
    
                     Locations:
                     SignInRiskLevels: System.Collections.Generic.List`1[Microsoft.Open.MSGraph.Model.ConditionalAccessRiskLevel]
                     ClientAppTypes: System.Collections.Generic.List`1[Microsoft.Open.MSGraph.Model.ConditionalAccessClientApp]
                   }
    
 GrantControls   : class ConditionalAccessGrantControls {
                     _Operator: OR
                     BuiltInControls: System.Collections.Generic.List`1[Microsoft.Open.MSGraph.Model.ConditionalAccessGrantControl]
                     CustomAuthenticationFactors: System.Collections.Generic.List`1[System.String]
                     TermsOfUse: System.Collections.Generic.List`1[System.String]
                   }
    
 SessionControls :

Condition section includes information about: applications, users, platforms, locations which is required to be retrieved

My script so far: Get-AzureADMSConditionalAccessPolicy | Select-Object -Property DisplayName, Id, State | Export-Csv -Path C:\CAccessResults.csv -NoTypeInformation



On further research, it looks like by running ((Get-AzureADMSConditionalAccessPolicy).Conditions).Applications can display

 PS C:\Windows\system32> ((Get-AzureADMSConditionalAccessPolicy).Conditions).Applications
    
 IncludeApplications ExcludeApplications IncludeUserActions IncludeProtectionLevels
 ------------------- ------------------- ------------------ -----------------------
 {Office365}         {}                  {}

and the same applies for users, platforms, locations and grantcontrols.

 PS C:\Windows\system32> ((Get-AzureADMSConditionalAccessPolicy).Conditions).users
    
    
 IncludeUsers  : {350a541a-02f0-4759-b729-70922997e819}
 ExcludeUsers  : {}
 IncludeGroups : {}
 ExcludeGroups : {}
 IncludeRoles  : {}
 ExcludeRoles  : {}

 PS C:\Windows\system32> ((Get-AzureADMSConditionalAccessPolicy).Conditions).users
    
    
 IncludeUsers  : {350a541a-02f0-4759-b729-70922997e819}
 ExcludeUsers  : {}
 IncludeGroups : {}
 ExcludeGroups : {}
 IncludeRoles  : {}
 ExcludeRoles  : {}

The user querry returns GUID.

My goal is to have this friendly readable information queried and stored in the csv file. How can that be implemented?

My script so far:

 $allpolicies = Get-AzureADMSConditionalAccessPolicy 
    
 $allpolicies | ForEach-Object{
    
     $policyID = $_.Id
     $policydisplayname = $_.DisplayName
     $policystate = $_.State
     $applications = ($_.Conditions).Applications.IncludeApplications
     $includedusers = ($_.Conditions).Users.IncludeUsers
     $includedgroups = ($_.Conditions).Users.IncludeGroups
     $includedlocation = ($_.Conditions).Locations.includelocations
    
    
     New-object -typename PSobject -property @{
    
         ID = $policyID
         DisplayName = $policydisplayname
         Policy_State = $policystate
         Includedapps =  $applications
         Users_Applied_The_Policy = $includedusers
         Groups_Applied_The_Policy = $includedgroups
         Locations_Applied_The_Policy = $includedlocation
    
    
     }
    
 } | Sort-Object ID, DisplayName, Policy_State, Includedapps, Users_Applied_Policy, Groups_Applied_Policy, Locations_Applied | Export-Csv -Path C:\CAccessResults3.csv -NoTypeInformation


CSV output:
179742-conditionalaccesscsv.png


Running the script using powershell without saving the output in csv
179713-conditionaaccesscoreps.png



Is there a way to output the values for Includedapps, Users_Applied_Policy, Groups_Applied_Policy, Locations_Applied in a readable format and have them separated in each row.

windows-server-powershellazure-ad-conditional-accessazure-ad-identity-governance
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

ClementBETACORNE avatar image
2 Votes"
ClementBETACORNE answered RichMatheisen-8856 commented

Hello,

You try to add a join at this part in your script :

 $allpolicies = Get-AzureADMSConditionalAccessPolicy 
        
  $allpolicies | ForEach-Object{
        
      $policyID = $_.Id
      $policydisplayname = $_.DisplayName
      $policystate = $_.State
      $applications = ($_.Conditions).Applications.IncludeApplications -join ' '
      $includedusers = ($_.Conditions).Users.IncludeUsers -join ' '
      $includedgroups = ($_.Conditions).Users.IncludeGroups -join ' '
      $includedlocation = ($_.Conditions).Locations.includelocations -join ' '
        
        
      New-object -typename PSobject -property @{
        
          ID = $policyID
          DisplayName = $policydisplayname
          Policy_State = $policystate
          Includedapps =  $applications
          Users_Applied_The_Policy = $includedusers
          Groups_Applied_The_Policy = $includedgroups
          Locations_Applied_The_Policy = $includedlocation
        
        
      }
        
  }

I've tested it with the export and you have something like that :
179765-image.png



image.png (39.2 KiB)
· 5
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

This works fine @ClementBETACORNE , is there a way to to translate the GUID of the user to the actual name or email address?

0 Votes 0 ·

Iterate over the list of users. For example:

 $includedusers -split " " |
     ForEach-Object{
         $guid = $_.objectGUID -replace "-",""
         $u = Get-ADUser -Identity $guid
         $mail = $u.$mail
         $acct = $u.samaccountname
         $name = $u.$name
         etc.
     }


0 Votes 0 ·

This looks understandable kindly can incorporate in the code how it will integrate. I'm confused whether to feed the loop in $includeusers variable or?

0 Votes 0 ·
Show more comments

Hello @bernardmwanza-0900 ,

You will have to use the Get-AzureADUser with -objectId parameter to translate the guid to something more readable. As RichMatheisen mentioned you will have to iterate over the list of users

Regards,

0 Votes 0 ·
ClementBETACORNE avatar image
0 Votes"
ClementBETACORNE answered

Hello,

You should use the DCToolBox module with the New-DCConditionalAccessPolicyDesignReport cmdlet :
https://danielchronlund.com/2020/11/09/dctoolbox-powershell-module-for-microsoft-365-security-conditional-access-automation-and-more/

Regards,

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

RichMatheisen-8856 avatar image
0 Votes"
RichMatheisen-8856 answered

CSV files aren't really geared towards representing structured data. You can place all of the values in a list into one column if you provide for a delimiter within the data that 1) doesn't exist in any data in the column, and 2) isn't the same delimiter used to separate the columns.

 [PSCustomObject]@{
     Includedapps = ($applications -join ';')
 }
    
 # OR without the need for the intermediate variable "$applications"
    
 [PSCustomObject]@{
     Includedapps = ($_.Conditions.Applications.IncludeApplications -join ';')
 }
    
 # THEN
 Export-CSV some-file-name.csv -NoTypeInformation -Delimiter ',' # Note: the comma is the default delimiter. 
                                                                 #       I just used it here to contrast with the semi-colon separator
                                                                 #       used within the column data
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

sikumars avatar image
0 Votes"
sikumars answered

You could use Get-AzureADUser -ObjectId 7ccb8dc7-c694-42d7-8242-bd5cf7d5a9f2 | Select UserPrincipalName to get UserPrincipalName of given user's Object ID as shown below:

189604-image.png



image.png (11.5 KiB)
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.