O365Essentials.psm1
function Join-UriQuery { <# .SYNOPSIS Provides ability to join two Url paths together including advanced querying .DESCRIPTION Provides ability to join two Url paths together including advanced querying which is useful for RestAPI/GraphApi calls .PARAMETER BaseUri Primary Url to merge .PARAMETER RelativeOrAbsoluteUri Additional path to merge with primary url (optional) .PARAMETER QueryParameter Parameters and their values in form of hashtable .PARAMETER EscapeUriString If set, will escape the url string .EXAMPLE Join-UriQuery -BaseUri 'https://evotec.xyz/' -RelativeOrAbsoluteUri '/wp-json/wp/v2/posts' -QueryParameter @{ page = 1 per_page = 20 search = 'SearchString' } .EXAMPLE Join-UriQuery -BaseUri 'https://evotec.xyz/wp-json/wp/v2/posts' -QueryParameter @{ page = 1 per_page = 20 search = 'SearchString' } .EXAMPLE Join-UriQuery -BaseUri 'https://evotec.xyz' -RelativeOrAbsoluteUri '/wp-json/wp/v2/posts' .NOTES General notes #> [alias('Join-UrlQuery')] [CmdletBinding()] param ( [parameter(Mandatory)][uri] $BaseUri, [parameter(Mandatory = $false)][uri] $RelativeOrAbsoluteUri, [Parameter()][System.Collections.IDictionary] $QueryParameter, [alias('EscapeUrlString')][switch] $EscapeUriString ) Begin { Add-Type -AssemblyName System.Web } Process { if ($BaseUri -and $RelativeOrAbsoluteUri) { $Url = Join-Uri -BaseUri $BaseUri -RelativeOrAbsoluteUri $RelativeOrAbsoluteUri } else { $Url = $BaseUri } if ($QueryParameter) { $Collection = [System.Web.HttpUtility]::ParseQueryString([String]::Empty) foreach ($key in $QueryParameter.Keys) { $Collection.Add($key, $QueryParameter.$key) } } $uriRequest = [System.UriBuilder] $Url if ($Collection) { $uriRequest.Query = $Collection.ToString() } if (-not $EscapeUriString) { $uriRequest.Uri.AbsoluteUri } else { [System.Uri]::EscapeUriString($uriRequest.Uri.AbsoluteUri) } } } function Remove-EmptyValue { <# .SYNOPSIS Removes empty values from a hashtable recursively. .DESCRIPTION This function removes empty values from a given hashtable. It can be used to clean up a hashtable by removing keys with null, empty string, empty array, or empty dictionary values. The function supports recursive removal of empty values. .PARAMETER Hashtable The hashtable from which empty values will be removed. .PARAMETER ExcludeParameter An array of keys to exclude from the removal process. .PARAMETER Recursive Indicates whether to recursively remove empty values from nested hashtables. .PARAMETER Rerun Specifies the number of times to rerun the removal process recursively. .PARAMETER DoNotRemoveNull If specified, null values will not be removed. .PARAMETER DoNotRemoveEmpty If specified, empty string values will not be removed. .PARAMETER DoNotRemoveEmptyArray If specified, empty array values will not be removed. .PARAMETER DoNotRemoveEmptyDictionary If specified, empty dictionary values will not be removed. .EXAMPLE $hashtable = @{ 'Key1' = ''; 'Key2' = $null; 'Key3' = @(); 'Key4' = @{} } Remove-EmptyValue -Hashtable $hashtable -Recursive Description ----------- This example removes empty values from the $hashtable recursively. #> [alias('Remove-EmptyValues')] [CmdletBinding()] param( [alias('Splat', 'IDictionary')][Parameter(Mandatory)][System.Collections.IDictionary] $Hashtable, [string[]] $ExcludeParameter, [switch] $Recursive, [int] $Rerun, [switch] $DoNotRemoveNull, [switch] $DoNotRemoveEmpty, [switch] $DoNotRemoveEmptyArray, [switch] $DoNotRemoveEmptyDictionary ) foreach ($Key in [string[]] $Hashtable.Keys) { if ($Key -notin $ExcludeParameter) { if ($Recursive) { if ($Hashtable[$Key] -is [System.Collections.IDictionary]) { if ($Hashtable[$Key].Count -eq 0) { if (-not $DoNotRemoveEmptyDictionary) { $Hashtable.Remove($Key) } } else { Remove-EmptyValue -Hashtable $Hashtable[$Key] -Recursive:$Recursive } } else { if (-not $DoNotRemoveNull -and $null -eq $Hashtable[$Key]) { $Hashtable.Remove($Key) } elseif (-not $DoNotRemoveEmpty -and $Hashtable[$Key] -is [string] -and $Hashtable[$Key] -eq '') { $Hashtable.Remove($Key) } elseif (-not $DoNotRemoveEmptyArray -and $Hashtable[$Key] -is [System.Collections.IList] -and $Hashtable[$Key].Count -eq 0) { $Hashtable.Remove($Key) } } } else { if (-not $DoNotRemoveNull -and $null -eq $Hashtable[$Key]) { $Hashtable.Remove($Key) } elseif (-not $DoNotRemoveEmpty -and $Hashtable[$Key] -is [string] -and $Hashtable[$Key] -eq '') { $Hashtable.Remove($Key) } elseif (-not $DoNotRemoveEmptyArray -and $Hashtable[$Key] -is [System.Collections.IList] -and $Hashtable[$Key].Count -eq 0) { $Hashtable.Remove($Key) } } } } if ($Rerun) { for ($i = 0; $i -lt $Rerun; $i++) { Remove-EmptyValue -Hashtable $Hashtable -Recursive:$Recursive } } } function Select-Properties { <# .SYNOPSIS Allows for easy selecting property names from one or multiple objects .DESCRIPTION Allows for easy selecting property names from one or multiple objects. This is especially useful with using AllProperties parameter where we want to make sure to get all properties from all objects. .PARAMETER Objects One or more objects .PARAMETER Property Properties to include .PARAMETER ExcludeProperty Properties to exclude .PARAMETER AllProperties All unique properties from all objects .PARAMETER PropertyNameReplacement Default property name when object has no properties .EXAMPLE $Object1 = [PSCustomobject] @{ Name1 = '1' Name2 = '3' Name3 = '5' } $Object2 = [PSCustomobject] @{ Name4 = '2' Name5 = '6' Name6 = '7' } Select-Properties -Objects $Object1, $Object2 -AllProperties #OR: $Object1, $Object2 | Select-Properties -AllProperties -ExcludeProperty Name6 -Property Name3 .EXAMPLE $Object3 = [Ordered] @{ Name1 = '1' Name2 = '3' Name3 = '5' } $Object4 = [Ordered] @{ Name4 = '2' Name5 = '6' Name6 = '7' } Select-Properties -Objects $Object3, $Object4 -AllProperties $Object3, $Object4 | Select-Properties -AllProperties .NOTES General notes #> [CmdLetBinding()] param( [Array][Parameter(Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)] $Objects, [string[]] $Property, [string[]] $ExcludeProperty, [switch] $AllProperties, [string] $PropertyNameReplacement = '*' ) Begin { function Select-Unique { [CmdLetBinding()] param( [System.Collections.IList] $Object ) [Array] $CleanedList = foreach ($O in $Object) { if ($null -ne $O) { $O } } $New = $CleanedList.ToLower() | Select-Object -Unique $Selected = foreach ($_ in $New) { $Index = $Object.ToLower().IndexOf($_) if ($Index -ne -1) { $Object[$Index] } } $Selected } $ObjectsList = [System.Collections.Generic.List[Object]]::new() } Process { foreach ($Object in $Objects) { $ObjectsList.Add($Object) } } End { if ($ObjectsList.Count -eq 0) { Write-Warning 'Select-Properties - Unable to process. Objects count equals 0.' return } if ($ObjectsList[0] -is [System.Collections.IDictionary]) { if ($AllProperties) { [Array] $All = foreach ($_ in $ObjectsList) { $_.Keys } $FirstObjectProperties = Select-Unique -Object $All } else { $FirstObjectProperties = $ObjectsList[0].Keys } if ($Property.Count -gt 0 -and $ExcludeProperty.Count -gt 0) { $FirstObjectProperties = foreach ($_ in $FirstObjectProperties) { if ($Property -contains $_ -and $ExcludeProperty -notcontains $_) { $_ continue } } } elseif ($Property.Count -gt 0) { $FirstObjectProperties = foreach ($_ in $FirstObjectProperties) { if ($Property -contains $_) { $_ continue } } } elseif ($ExcludeProperty.Count -gt 0) { $FirstObjectProperties = foreach ($_ in $FirstObjectProperties) { if ($ExcludeProperty -notcontains $_) { $_ continue } } } } elseif ($ObjectsList[0].GetType().Name -match 'bool|byte|char|datetime|decimal|double|ExcelHyperLink|float|int|long|sbyte|short|string|timespan|uint|ulong|URI|ushort') { $FirstObjectProperties = $PropertyNameReplacement } else { if ($Property.Count -gt 0 -and $ExcludeProperty.Count -gt 0) { $ObjectsList = $ObjectsList | Select-Object -Property $Property -ExcludeProperty $ExcludeProperty } elseif ($Property.Count -gt 0) { $ObjectsList = $ObjectsList | Select-Object -Property $Property } elseif ($ExcludeProperty.Count -gt 0) { $ObjectsList = $ObjectsList | Select-Object -Property '*' -ExcludeProperty $ExcludeProperty } if ($AllProperties) { [Array] $All = foreach ($_ in $ObjectsList) { $ListProperties = $_.PSObject.Properties.Name if ($null -ne $ListProperties) { $ListProperties } } $FirstObjectProperties = Select-Unique -Object $All } else { $FirstObjectProperties = $ObjectsList[0].PSObject.Properties.Name } } $FirstObjectProperties } } function Join-Uri { <# .SYNOPSIS Provides ability to join two Url paths together .DESCRIPTION Provides ability to join two Url paths together .PARAMETER BaseUri Primary Url to merge .PARAMETER RelativeOrAbsoluteUri Additional path to merge with primary url .EXAMPLE Join-Uri 'https://evotec.xyz/' '/wp-json/wp/v2/posts' .EXAMPLE Join-Uri 'https://evotec.xyz/' 'wp-json/wp/v2/posts' .EXAMPLE Join-Uri -BaseUri 'https://evotec.xyz/' -RelativeOrAbsoluteUri '/wp-json/wp/v2/posts' .EXAMPLE Join-Uri -BaseUri 'https://evotec.xyz/test/' -RelativeOrAbsoluteUri '/wp-json/wp/v2/posts' .NOTES General notes #> [alias('Join-Url')] [cmdletBinding()] param( [parameter(Mandatory)][uri] $BaseUri, [parameter(Mandatory)][uri] $RelativeOrAbsoluteUri ) return ($BaseUri.OriginalString.TrimEnd('/') + "/" + $RelativeOrAbsoluteUri.OriginalString.TrimStart('/')) } function Convert-AzureEnterpriseAppsUserConsent { <# .SYNOPSIS Converts Azure Enterprise Apps user consent policies between internal and external representations. .DESCRIPTION This function translates Azure Enterprise Apps user consent policies from their internal representation to a more user-friendly format and vice versa. It can be used to convert policies for display or for processing by other functions. .PARAMETER PermissionsGrantPoliciesAssigned An array of policies assigned to the user. The function processes the first element of this array. .PARAMETER Reverse A switch parameter. If specified, the function performs the reverse translation, converting user-friendly policy names back to their internal representations. .EXAMPLE Convert-AzureEnterpriseAppsUserConsent -PermissionsGrantPoliciesAssigned @('ManagePermissionGrantsForSelf.microsoft-user-default-legacy') This example converts the internal policy 'ManagePermissionGrantsForSelf.microsoft-user-default-legacy' to 'AllowUserConsentForApps'. .EXAMPLE Convert-AzureEnterpriseAppsUserConsent -PermissionsGrantPoliciesAssigned @('AllowUserConsentForApps') -Reverse This example converts the user-friendly policy 'AllowUserConsentForApps' back to its internal representation 'ManagePermissionGrantsForSelf.microsoft-user-default-legacy'. .NOTES This function only processes the first element of the PermissionsGrantPoliciesAssigned array. #> [cmdletbinding()] param( [Array] $PermissionsGrantPoliciesAssigned, [switch] $Reverse ) $StringToProcess = $PermissionsGrantPoliciesAssigned[0] if (-not $Reverse) { $TranslatePermissions = @{ 'ManagePermissionGrantsForSelf.microsoft-user-default-legacy' = 'AllowUserConsentForApps' 'ManagePermissionGrantsForSelf.microsoft-user-default-low' = 'AllowUserConsentForSelectedPermissions' } if ($StringToProcess -and $TranslatePermissions[$StringToProcess]) { $TranslatePermissions[$StringToProcess] } else { 'DoNotAllowUserConsent' } } else { $TranslatePermissions = @{ 'AllowUserConsentForApps' = 'ManagePermissionGrantsForSelf.microsoft-user-default-legacy' 'AllowUserConsentForSelectedPermissions' = 'ManagePermissionGrantsForSelf.microsoft-user-default-low' 'DoNotAllowUserConsent' = '' } $TranslatePermissions[$StringToProcess] } } function Convert-AzureRole { <# .SYNOPSIS Converts Azure role IDs to their corresponding role names. .DESCRIPTION This function takes one or more Azure role IDs and converts them to their human-readable role names. If the -All switch is used, it returns all available role names. .PARAMETER RoleID An array of Azure role IDs to be converted to role names. .PARAMETER All A switch parameter. If specified, the function returns all role names available in the system. .EXAMPLE Convert-AzureRole -RoleID '62e90394-69f5-4237-9190-012177145e10' Returns 'Global Administrator'. .EXAMPLE Convert-AzureRole -All Returns all role names available in the system. .NOTES This function is useful for mapping role IDs to their descriptive names in scripts and reports. #> [cmdletbinding()] param( [string[]] $RoleID, [switch] $All ) $Roles = [ordered] @{ '62e90394-69f5-4237-9190-012177145e10' = 'Global Administrator' # True '10dae51f-b6af-4016-8d66-8c2a99b929b3' = 'Guest User' # True '2af84b1e-32c8-42b7-82bc-daa82404023b' = 'Restricted Guest User' # True '95e79109-95c0-4d8e-aee3-d01accf2d47b' = 'Guest Inviter' # True 'fe930be7-5e62-47db-91af-98c3a49a38b1' = 'User Administrator' # True '729827e3-9c14-49f7-bb1b-9608f156bbb8' = 'Helpdesk Administrator' # True 'f023fd81-a637-4b56-95fd-791ac0226033' = 'Service Support Administrator' # True 'b0f54661-2d74-4c50-afa3-1ec803f12efe' = 'Billing Administrator' # True 'a0b1b346-4d3e-4e8b-98f8-753987be4970' = 'User' # True '4ba39ca4-527c-499a-b93d-d9b492c50246' = 'Partner Tier1 Support' # True 'e00e864a-17c5-4a4b-9c06-f5b95a8d5bd8' = 'Partner Tier2 Support' # True '88d8e3e3-8f55-4a1e-953a-9b9898b8876b' = 'Directory Readers' # True '9360feb5-f418-4baa-8175-e2a00bac4301' = 'Directory Writers' # True '29232cdf-9323-42fd-ade2-1d097af3e4de' = 'Exchange Administrator' # True 'f28a1f50-f6e7-4571-818b-6a12f2af6b6c' = 'SharePoint Administrator' # True '75941009-915a-4869-abe7-691bff18279e' = 'Skype for Business Administrator' # True 'd405c6df-0af8-4e3b-95e4-4d06e542189e' = 'Device Users' # True '9f06204d-73c1-4d4c-880a-6edb90606fd8' = 'Azure AD Joined Device Local Administrator' # True '9c094953-4995-41c8-84c8-3ebb9b32c93f' = 'Device Join' # True 'c34f683f-4d5a-4403-affd-6615e00e3a7f' = 'Workplace Device Join' # True '17315797-102d-40b4-93e0-432062caca18' = 'Compliance Administrator' # True 'd29b2b05-8046-44ba-8758-1e26182fcf32' = 'Directory Synchronization Accounts' # True '2b499bcd-da44-4968-8aec-78e1674fa64d' = 'Device Managers' # True '9b895d92-2cd3-44c7-9d02-a6ac2d5ea5c3' = 'Application Administrator' # True 'cf1c38e5-3621-4004-a7cb-879624dced7c' = 'Application Developer' # True '5d6b6bb7-de71-4623-b4af-96380a352509' = 'Security Reader' # True '194ae4cb-b126-40b2-bd5b-6091b380977d' = 'Security Administrator' # True 'e8611ab8-c189-46e8-94e1-60213ab1f814' = 'Privileged Role Administrator' # True '3a2c62db-5318-420d-8d74-23affee5d9d5' = 'Intune Administrator' # True '158c047a-c907-4556-b7ef-446551a6b5f7' = 'Cloud Application Administrator' # True '5c4f9dcd-47dc-4cf7-8c9a-9e4207cbfc91' = 'Customer LockBox Access Approver' # True '44367163-eba1-44c3-98af-f5787879f96a' = 'Dynamics 365 Administrator' # True 'a9ea8996-122f-4c74-9520-8edcd192826c' = 'Power BI Administrator' # True 'b1be1c3e-b65d-4f19-8427-f6fa0d97feb9' = 'Conditional Access Administrator' # True '4a5d8f65-41da-4de4-8968-e035b65339cf' = 'Reports Reader' # True '790c1fb9-7f7d-4f88-86a1-ef1f95c05c1b' = 'Message Center Reader' # True '7495fdc4-34c4-4d15-a289-98788ce399fd' = 'Azure Information Protection Administrator' # True '38a96431-2bdf-4b4c-8b6e-5d3d8abac1a4' = 'Desktop Analytics Administrator' # True '4d6ac14f-3453-41d0-bef9-a3e0c569773a' = 'License Administrator' # True '7698a772-787b-4ac8-901f-60d6b08affd2' = 'Cloud Device Administrator' # True 'c4e39bd9-1100-46d3-8c65-fb160da0071f' = 'Authentication Administrator' # True '7be44c8a-adaf-4e2a-84d6-ab2649e08a13' = 'Privileged Authentication Administrator' # True 'baf37b3a-610e-45da-9e62-d9d1e5e8914b' = 'Teams Communications Administrator' # True 'f70938a0-fc10-4177-9e90-2178f8765737' = 'Teams Communications Support Engineer' # True 'fcf91098-03e3-41a9-b5ba-6f0ec8188a12' = 'Teams Communications Support Specialist' # True '69091246-20e8-4a56-aa4d-066075b2a7a8' = 'Teams Administrator' # True 'eb1f4a8d-243a-41f0-9fbd-c7cdf6c5ef7c' = 'Insights Administrator' # True 'ac16e43d-7b2d-40e0-ac05-243ff356ab5b' = 'Message Center Privacy Reader' # True '6e591065-9bad-43ed-90f3-e9424366d2f0' = 'External ID User Flow Administrator' # True '0f971eea-41eb-4569-a71e-57bb8a3eff1e' = 'External ID User Flow Attribute Administrator' # True 'aaf43236-0c0d-4d5f-883a-6955382ac081' = 'B2C IEF Keyset Administrator' # True '3edaf663-341e-4475-9f94-5c398ef6c070' = 'B2C IEF Policy Administrator' # True 'be2f45a1-457d-42af-a067-6ec1fa63bc45' = 'External Identity Provider Administrator' # True 'e6d1a23a-da11-4be4-9570-befc86d067a7' = 'Compliance Data Administrator' # True '5f2222b1-57c3-48ba-8ad5-d4759f1fde6f' = 'Security Operator' # True '74ef975b-6605-40af-a5d2-b9539d836353' = 'Kaizala Administrator' # True 'f2ef992c-3afb-46b9-b7cf-a126ee74c451' = 'Global Reader' # True '0964bb5e-9bdb-4d7b-ac29-58e794862a40' = 'Search Administrator' # True '8835291a-918c-4fd7-a9ce-faa49f0cf7d9' = 'Search Editor' # True '966707d0-3269-4727-9be2-8c3a10f19b9d' = 'Password Administrator' # True '644ef478-e28f-4e28-b9dc-3fdde9aa0b1f' = 'Printer Administrator' # True 'e8cef6f1-e4bd-4ea8-bc07-4b8d950f4477' = 'Printer Technician' # True '0526716b-113d-4c15-b2c8-68e3c22b9f80' = 'Authentication Policy Administrator' # True 'fdd7a751-b60b-444a-984c-02652fe8fa1c' = 'Groups Administrator' # True '11648597-926c-4cf3-9c36-bcebb0ba8dcc' = 'Power Platform Administrator' # True 'e3973bdf-4987-49ae-837a-ba8e231c7286' = 'Azure DevOps Administrator' # True '8ac3fc64-6eca-42ea-9e69-59f4c7b60eb2' = 'Hybrid Identity Administrator' # True '2b745bdf-0803-4d80-aa65-822c4493daac' = 'Office Apps Administrator' # True 'd37c8bed-0711-4417-ba38-b4abe66ce4c2' = 'Network Administrator' # True '31e939ad-9672-4796-9c2e-873181342d2d' = 'Insights Business Leader' # True '3d762c5a-1b6c-493f-843e-55a3b42923d4' = 'Teams Devices Administrator' # True 'c430b396-e693-46cc-96f3-db01bf8bb62a' = 'Attack Simulation Administrator' # True '9c6df0f2-1e7c-4dc3-b195-66dfbd24aa8f' = 'Attack Payload Author' # True '75934031-6c7e-415a-99d7-48dbd49e875e' = 'Usage Summary Reports Reader' # True 'b5a8dcf3-09d5-43a9-a639-8e29ef291470' = 'Knowledge Administrator' # True '744ec460-397e-42ad-a462-8b3f9747a02c' = 'Knowledge Manager' # True '8329153b-31d0-4727-b945-745eb3bc5f31' = 'Domain Name Administrator' # True '31392ffb-586c-42d1-9346-e59415a2cc4e' = 'Exchange Recipient Administrator' # True '45d8d3c5-c802-45c6-b32a-1d70b5e1e86e' = 'Identity Governance Administrator' # True '892c5842-a9a6-463a-8041-72aa08ca3cf6' = 'Cloud App Security Administrator' # True '32696413-001a-46ae-978c-ce0f6b3620d2' = 'Windows Update Deployment Administrator' # True } if ($All) { $Roles.Values } else { foreach ($Role in $RoleID) { $RoleName = $Roles[$Role] if ($RoleName) { $RoleName } else { $Role } } } } function Convert-CompanyType { <# .SYNOPSIS Converts company type codes to their descriptive names. .DESCRIPTION This function takes an array of company type codes and converts each code to its corresponding descriptive name. If a code does not have a corresponding name, the code itself is returned. .PARAMETER CompanyType An array of company type codes that need to be converted to descriptive names. .EXAMPLE Convert-CompanyType -CompanyType '5', '4' # Returns 'Indirect reseller', 'Reseller' .EXAMPLE Convert-CompanyType -CompanyType '5', '1' # Returns 'Indirect reseller', '1' # Note: '1' is returned as is because it does not have a corresponding name in the mapping. .NOTES Current mappings include: '5' for 'Indirect reseller' '4' for 'Reseller' #> [cmdletbinding()] param( [string[]] $CompanyType ) $CompanyTypeInformation = [ordered] @{ '5' = 'Indirect reseller' '4' = 'Reseller' } foreach ($Company in $CompanyType) { $CompanyName = $CompanyTypeInformation[$Company] if ($CompanyName) { $CompanyName } else { $Company } } } function Convert-ContractType { <# .SYNOPSIS Converts contract type codes to their descriptive names. .DESCRIPTION This function takes an array of contract type codes and converts each code to its corresponding descriptive name. If a code does not have a corresponding name, the code itself is returned. .PARAMETER ContractType An array of contract type codes that need to be converted to descriptive names. .EXAMPLE Convert-ContractType -ContractType '3', '1' # Returns 'Reseller', '1' # Note: '1' is returned as is because it does not have a corresponding name in the mapping. .NOTES Current mappings include: '3' for 'Reseller' #> [cmdletbinding()] param( [string[]] $ContractType ) $ContractTypeInformation = [ordered] @{ '3' = 'Reseller' } foreach ($Contract in $ContractType) { $ContractName = $ContractTypeInformation[$Contract] if ($ContractName) { $ContractName } else { $Contract } } } function Convert-SKUToLicense { <# .SYNOPSIS Converts a SKU to its corresponding license details. .DESCRIPTION This function takes a SKU (Stock Keeping Unit) identifier and retrieves the associated service plans and license details. .PARAMETER SKU The SKU identifier for which the license details need to be retrieved. .EXAMPLE Convert-SKUToLicense -SKU "ENTERPRISEPACK" # Returns the service plans and license details for the specified SKU. .NOTES This function relies on the Get-O365AzureLicenses cmdlet to fetch the license details. #> [cmdletbinding()] param( [parameter()][string] $SKU ) $ServicePlans = Get-O365AzureLicenses -LicenseSKUID $SKU -ServicePlans -IncludeLicenseDetails if ($ServicePlans) { $ServicePlans } } function Find-EnabledServicePlan { <# .SYNOPSIS Identifies enabled and disabled service plans from a given list. .DESCRIPTION This function takes two arrays: one containing all service plans and another containing disabled service plans. It returns an ordered dictionary with two keys: 'Enabled' and 'Disabled'. The 'Enabled' key contains an array of service plans that are not in the disabled list, and the 'Disabled' key contains an array of service plans that are in the disabled list. .PARAMETER ServicePlans An array of all available service plans. .PARAMETER DisabledServicePlans An array of service plans that are disabled. .EXAMPLE $allPlans = @('PlanA', 'PlanB', 'PlanC') $disabledPlans = @('PlanB') $result = Find-EnabledServicePlan -ServicePlans $allPlans -DisabledServicePlans $disabledPlans # $result.Enabled will contain 'PlanA' and 'PlanC' # $result.Disabled will contain 'PlanB' .NOTES This function is useful for categorizing service plans into enabled and disabled groups. #> [cmdletbinding()] param( [Array] $ServicePlans, [Array] $DisabledServicePlans ) $CachePlan = @{} foreach ($Plan in $ServicePlans) { $CachePlan[$Plan.serviceName] = $Plan } $Plans = [ordered] @{ Enabled = $null Disabled = $null } if ($DisabledServicePlans.Count -gt 0) { [Array] $Plans['Enabled'] = foreach ($Plan in $ServicePlans) { if ($Plan.serviceName -notin $DisabledServicePlans) { $Plan } } } else { [Array] $Plans['Enabled'] = $ServicePlans } [Array] $Plans['Disabled'] = foreach ($Plan in $DisabledServicePlans) { $CachePlan[$Plan] } $Plans } function Get-O365PrivateUserOrSPN { <# .SYNOPSIS Retrieves an Office 365 user or service principal by their principal ID. .DESCRIPTION This function attempts to retrieve an Office 365 user or service principal using the provided principal ID. It first tries to find a user with the given ID. If no user is found, it then tries to find a service principal with the same ID. If neither a user nor a service principal is found, it outputs any warnings encountered during the process. .PARAMETER PrincipalID The ID of the principal (user or service principal) to retrieve. .EXAMPLE $principal = Get-O365PrivateUserOrSPN -PrincipalID "user@example.com" This example retrieves the Office 365 user or service principal with the ID "user@example.com". .NOTES This function is useful for identifying whether a given principal ID corresponds to a user or a service principal in Office 365. #> [cmdletBinding()] param( [string] $PrincipalID ) $OutputUser = Get-O365User -Id $PrincipalID -WarningAction SilentlyContinue -WarningVariable varWarning if ($OutputUser) { $OutputUser } else { $OutputService = Get-O365ServicePrincipal -Id $PrincipalID -WarningAction SilentlyContinue -WarningVariable +varWarning if ($OutputService) { $OutputService } } if (-not $OutputService -and -not $OutputUser) { foreach ($Warning in $VarWarning) { Write-Warning -Message $Warning } } } $Script:O365PolicyState = @{ '2' = 'Report-only' '1' = 'Off' '0' = 'On' # i think } function Connect-O365Admin { <# .SYNOPSIS Connects to Office 365 as an administrator. .DESCRIPTION This function establishes a connection to Office 365 using provided credentials or cached authorization tokens. It supports multiple authentication methods and handles token refreshes as needed. .PARAMETER Credential The PSCredential object containing the username and password for authentication. .PARAMETER Headers A dictionary containing authorization headers, including tokens and expiration information. .PARAMETER ExpiresIn The duration in seconds for which the token is valid. Default is 3600 seconds. .PARAMETER ExpiresTimeout The timeout in seconds before the token expires to initiate a refresh. Default is 30 seconds. .PARAMETER ForceRefresh A switch to force the refresh of the authorization token, even if it is not expired. .PARAMETER Tenant The tenant ID for the Office 365 subscription. .PARAMETER DomainName The domain name associated with the Office 365 tenant. .PARAMETER Subscription The subscription ID for the Office 365 service. .EXAMPLE Connect-O365Admin -Credential (Get-Credential) -Tenant "your-tenant-id" This example connects to Office 365 using the provided credentials and tenant ID. .EXAMPLE Connect-O365Admin -Headers $headers -ForceRefresh This example connects to Office 365 using the provided headers and forces a token refresh. .NOTES This function is useful for administrators who need to manage Office 365 services and require a reliable way to authenticate and maintain session tokens. #> [cmdletbinding(DefaultParameterSetName = 'Credential')] param( [parameter(ParameterSetName = 'Credential')][PSCredential] $Credential, [parameter(ParameterSetName = 'Headers', DontShow)][alias('Authorization')][System.Collections.IDictionary] $Headers, [int] $ExpiresIn = 3600, [int] $ExpiresTimeout = 30, [switch] $ForceRefresh, [alias('TenantID')][string] $Tenant, [string] $DomainName, [string] $Subscription ) if ($Headers) { if ($Headers.ExpiresOnUTC -gt [datetime]::UtcNow -and -not $ForceRefresh) { Write-Verbose -Message "Connect-O365Admin - Using cache for connection $($Headers.UserName)" return $Headers } else { # if header is expired, we need to use it's values to try and push it for refresh $Credential = $Headers.Credential $Tenant = $Headers.Tenant $Subscription = $Headers.Subscription } } elseif ($Script:AuthorizationO365Cache) { if ($Script:AuthorizationO365Cache.ExpiresOnUTC -gt [datetime]::UtcNow -and -not $ForceRefresh) { Write-Verbose -Message "Connect-O365Admin - Using cache for connection $($Script:AuthorizationO365Cache.UserName)" return $Script:AuthorizationO365Cache } else { $Credential = $Script:AuthorizationO365Cache.Credential $Tenant = $Script:AuthorizationO365Cache.Tenant $Subscription = $Script:AuthorizationO365Cache.Subscription } } if ($DomainName) { Write-Verbose -Message "Connect-O365Admin - Querying tenant to get domain name" $Tenant = Get-O365TenantID -DomainName $DomainName } try { $connectAzAccountSplat = @{ Credential = $Credential ErrorAction = 'Stop' TenantId = $Tenant Subscription = $Subscription } Remove-EmptyValue -Hashtable $connectAzAccountSplat if ($Credential) { Write-Verbose -Message "Connect-O365Admin - Connecting to Office 365 using Connect-AzAccount ($($Credential.UserName))" } else { Write-Verbose -Message "Connect-O365Admin - Connecting to Office 365 using Connect-AzAccount" } $AzConnect = (Connect-AzAccount @connectAzAccountSplat -WarningVariable warningAzAccount -WarningAction SilentlyContinue ) } catch { if ($_.CategoryInfo.Reason -eq 'AzPSAuthenticationFailedException') { if ($Credential) { Write-Warning -Message "Connect-O365Admin - Tenant most likely requires MFA. Please drop credential parameter, and just let the Connect-O365Admin prompt you for them." } else { Write-Warning -Message "Connect-O365Admin - Please provide DomainName or TenantID parameter." } } else { Write-Warning -Message "Connect-O365Admin - Error: $($_.Exception.Message)" } return } $Context = $AzConnect.Context try { Write-Verbose -Message "Connect-O365Admin - Establishing tokens for O365" $AuthenticationO365 = [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.AuthenticationFactory.Authenticate( $Context.Account, $Context.Environment, $Context.Tenant.Id.ToString(), $null, [Microsoft.Azure.Commands.Common.Authentication.ShowDialog]::Auto, $null, 'https://admin.microsoft.com' ) } catch { Write-Warning -Message "Connect-O365Admin - Authentication failure. Error: $($_.Exception.Message)" return } try { Write-Verbose -Message "Connect-O365Admin - Establishing tokens for Azure" $AuthenticationAzure = [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.AuthenticationFactory.Authenticate( $Context.Account, $Context.Environment, $Context.Tenant.Id.ToString(), $null, [Microsoft.Azure.Commands.Common.Authentication.ShowDialog]::Auto, $null, "74658136-14ec-4630-ad9b-26e160ff0fc6" ) } catch { Write-Warning -Message "Connect-O365Admin - Authentication failure. Error: $($_.Exception.Message)" return } try { Write-Verbose -Message "Connect-O365Admin - Establishing tokens for Graph" $AuthenticationGraph = [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.AuthenticationFactory.Authenticate( $Context.Account, $Context.Environment, $Context.Tenant.Id.ToString(), $null, [Microsoft.Azure.Commands.Common.Authentication.ShowDialog]::Auto, $null, "https://graph.microsoft.com" ) } catch { Write-Warning -Message "Connect-O365Admin - Authentication failure. Error: $($_.Exception.Message)" return } Write-Verbose -Message "Connect-O365Admin - Disconnecting from O365 using Disconnect-AzAccount" $null = Disconnect-AzAccount -AzureContext $Context $Script:AuthorizationO365Cache = [ordered] @{ 'Credential' = $Credential 'UserName' = $Context.Account 'Environment' = $Context.Environment 'Subscription' = $Subscription 'Tenant' = if ($Tenant) { $Tenant } else { $Context.Tenant.Id } 'ExpiresOnUTC' = ([datetime]::UtcNow).AddSeconds($ExpiresIn - $ExpiresTimeout) # This authorization is used for admin.microsoft.com 'AuthenticationO365' = $AuthenticationO365 'AccessTokenO365' = $AuthenticationO365.AccessToken 'HeadersO365' = [ordered] @{ "Content-Type" = "application/json; charset=UTF-8" "Authorization" = "Bearer $($AuthenticationO365.AccessToken)" 'X-Requested-With' = 'XMLHttpRequest' 'x-ms-client-request-id' = [guid]::NewGuid() 'x-ms-correlation-id' = [guid]::NewGuid() } # This authorization is used for azure stuff 'AuthenticationAzure' = $AuthenticationAzure 'AccessTokenAzure' = $AuthenticationAzure.AccessToken 'HeadersAzure' = [ordered] @{ "Content-Type" = "application/json; charset=UTF-8" "Authorization" = "Bearer $($AuthenticationAzure.AccessToken)" 'X-Requested-With' = 'XMLHttpRequest' 'x-ms-client-request-id' = [guid]::NewGuid() 'x-ms-correlation-id' = [guid]::NewGuid() } 'AuthenticationGraph' = $AuthenticationGraph 'AccessTokenGraph' = $AuthenticationGraph.AccessToken 'HeadersGraph' = [ordered] @{ "Content-Type" = "application/json; charset=UTF-8" ; "Authorization" = "Bearer $($AuthenticationGraph.AccessToken)" 'X-Requested-With' = 'XMLHttpRequest' 'x-ms-client-request-id' = [guid]::NewGuid() 'x-ms-correlation-id' = [guid]::NewGuid() } } $Script:AuthorizationO365Cache } function ConvertFrom-JSONWebToken { <# .SYNOPSIS Converts JWT token to PowerShell object allowing for easier analysis. .DESCRIPTION Converts JWT token to PowerShell object allowing for easier analysis. .PARAMETER Token Provide Token to convert to PowerShell object .PARAMETER IncludeHeader Include header as part of ordered dictionary .EXAMPLE ConvertFrom-JSONWebToken -Token ..... .NOTES Based on https://www.michev.info/Blog/Post/2140/decode-jwt-access-and-id-tokens-via-powershell Basically does what: https://jwt.ms/ and https://jwt.io/ do for you online #> [cmdletbinding()] param( [Parameter(Mandatory = $true)][string]$Token, [switch] $IncludeHeader ) # Validate as per https://tools.ietf.org/html/rfc7519 # Access and ID tokens are fine, Refresh tokens will not work if (!$Token.Contains(".") -or !$Token.StartsWith("eyJ")) { Write-Warning -Message "ConvertFrom-JSONWebToken - Wrong token. Skipping." return } # Extract header and payload $tokenheader, $tokenPayload = $Token.Split(".").Replace('-', '+').Replace('_', '/')[0..1] # Fix padding as needed, keep adding "=" until string length modulus 4 reaches 0 while ($tokenheader.Length % 4) { $tokenheader += "=" } # Invalid length for a Base-64 char array or string, adding = while ($tokenPayload.Length % 4) { $tokenPayload += "=" } # Convert header from Base64 encoded string to PSObject all at once $header = [System.Text.Encoding]::UTF8.GetString([system.convert]::FromBase64String($tokenheader)) | ConvertFrom-Json # Convert payload to string array $tokenArray = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($tokenPayload)) # Convert from JSON to PSObject $TokenObject = $tokenArray | ConvertFrom-Json # Signature foreach ($i in 0..2) { $Signature = $Token.Split('.')[$i].Replace('-', '+').Replace('_', '/') switch ($Signature.Length % 4) { 0 { break } 2 { $Signature += '==' } 3 { $Signature += '=' } } } $TokenObject | Add-Member -Type NoteProperty -Name "signature" -Value $Signature # Convert Expire time to PowerShell DateTime $DateZero = (Get-Date -Year 1970 -Month 1 -Day 1 -Hour 0 -Minute 0 -Second 0 -Millisecond 0) $TimeZone = Get-TimeZone $UTC = $DateZero.AddSeconds($TokenObject.exp) $Offset = $TimeZone.GetUtcOffset($(Get-Date)).TotalMinutes $LocalTime = $UTC.AddMinutes($Offset) Add-Member -Type NoteProperty -Name "expires" -Value $LocalTime -InputObject $TokenObject # Time to Expire $TimeToExpire = ($LocalTime - (Get-Date)) Add-Member -Type NoteProperty -Name "timeToExpire" -Value $TimeToExpire -InputObject $TokenObject if ($IncludeHeader) { [ordered] @{ Header = $header Token = $TokenObject } } else { $TokenObject } } function Disconnect-O365Admin { <# .SYNOPSIS Disconnects from Office 365 as an administrator by clearing cached authorization data. .DESCRIPTION This function disconnects the current PowerShell session from Office 365 by removing cached authorization data. It is a quick and dirty method to force disconnection from Office 365 services. .EXAMPLE Disconnect-O365Admin This example disconnects the current PowerShell session from Office 365 by clearing cached authorization data. .NOTES This function is useful for administrators who need to explicitly disconnect from Office 365 services, ensuring a clean session state. #> [CmdletBinding()] param( ) # quick and dirty removal of cached data that should force disconnection $Script:AuthorizationO365Cache = $null } function Get-O365AzureADConnect { <# .SYNOPSIS Retrieves the status of Azure AD Connect for Office 365. .DESCRIPTION This function calls the Azure AD API to get the status of password synchronization and AD Connect status. It returns a custom PowerShell object containing various synchronization and configuration details. .PARAMETER Headers Authorization header as created by Connect-O365Admin. If not provided the function will try to fetch it from the current execution context. .EXAMPLE Get-O365AzureADConnect -Verbose .NOTES https://portal.azure.com/#blade/Microsoft_AAD_IAM/PassThroughAuthenticationConnectorsBlade #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://main.iam.ad.ext.azure.com/api/Directories/GetPasswordSyncStatus" $Output3 = Invoke-O365Admin -Uri $Uri -Headers $Headers #$Output3 | Format-Table $Uri = "https://main.iam.ad.ext.azure.com/api/Directories/ADConnectStatus" $Output4 = Invoke-O365Admin -Uri $Uri -Headers $Headers [PSCustomObject] @{ passwordSyncStatus = $Output3 verifiedDomainCount = $Output4.verifiedDomainCount #: 3 verifiedCustomDomainCount = $Output4.verifiedCustomDomainCount #: 2 federatedDomainCount = $Output4.federatedDomainCount #: 0 numberOfHoursFromLastSync = $Output4.numberOfHoursFromLastSync #: 0 dirSyncEnabled = $Output4.dirSyncEnabled #: True dirSyncConfigured = $Output4.dirSyncConfigured #: True passThroughAuthenticationEnabled = $Output4.passThroughAuthenticationEnabled #: True seamlessSingleSignOnEnabled = $Output4.seamlessSingleSignOnEnabled #: True } } function Get-O365AzureADConnectPTA { <# .SYNOPSIS Retrieves the status of Pass-Through Authentication (PTA) connectors for Office 365. .DESCRIPTION This function calls the Azure AD API to get the status of Pass-Through Authentication (PTA) connectors. It returns the details of the PTA connector groups. .PARAMETER Headers Authorization header as created by Connect-O365Admin. If not provided the function will try to fetch it from the current execution context. .EXAMPLE Get-O365AzureADConnectPTA -Headers $headers .NOTES https://portal.azure.com/#blade/Microsoft_AAD_IAM/PassThroughAuthenticationConnectorsBlade #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://main.iam.ad.ext.azure.com/api/Directories/PassThroughAuthConnectorGroups" $Output1 = Invoke-O365Admin -Uri $Uri -Headers $Headers $Output1 } function Get-O365AzureADConnectSSO { <# .SYNOPSIS Retrieves information about Azure AD Connect with Pass-Through Authentication (PTA). .DESCRIPTION This function retrieves detailed information about Azure AD Connect with Pass-Through Authentication (PTA) connectors. .PARAMETER Headers Authorization header as created by Connect-O365Admin. If not provided the function will try to fetch it from the current execution context. .EXAMPLE Get-O365AzureADConnect -Verbose .NOTES For more information, visit: https://portal.azure.com/#blade/Microsoft_AAD_IAM/PassThroughAuthenticationConnectorsBlade #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://main.iam.ad.ext.azure.com/api/Directories/GetSeamlessSingleSignOnDomains" $Output2 = Invoke-O365Admin -Uri $Uri -Headers $Headers $Output2 } function Get-O365AzureADRoles { <# .SYNOPSIS Retrieves Azure AD roles from Microsoft Graph API. .DESCRIPTION This function retrieves Azure AD roles from the Microsoft Graph API based on the provided URI. It returns a list of Azure AD roles. #> [cmdletBinding()] param( ) #https://graph.microsoft.com/beta/roleManagement/directory/roleAssignments&$filter=roleDefinitionId eq ‘<object-id-or-template-id-of-role-definition>’ #$Uri = 'https://main.iam.ad.ext.azure.com/api/Roles/User/e6a8f1cf-0874-4323-a12f-2bf51bb6dfdd/RoleAssignments?scope=undefined' $Uri = 'https://graph.microsoft.com/v1.0/roleManagement/directory/roleDefinitions' <# $QueryParameter = @{ '$Select' = $Property -join ',' '$filter' = $Filter '$orderby' = $OrderBy } #> <# GET https://graph.microsoft.com/beta/roleManagement/directory/roleDefinitions?$filter=DisplayName eq 'Conditional Access Administrator'&$select=rolePermissions #> Write-Verbose -Message "Get-O365AzureADRoles - Getting all Azure AD Roles" $Script:AzureADRolesList = [ordered] @{} $Script:AzureADRolesListReverse = [ordered] @{} $RolesList = Invoke-O365Admin -Uri $Uri -Headers $Headers -QueryParameter $QueryParameter -Method GET $Script:AzureADRoles = $RolesList foreach ($Role in $RolesList) { $Script:AzureADRolesList[$Role.id] = $Role $Script:AzureADRolesListReverse[$Role.displayName] = $Role } $RolesList } <# Invoke-WebRequest -Uri "https://main.iam.ad.ext.azure.com/api/Roles/User/e6a8f1cf-0874-4323-a12f-2bf51bb6dfdd/RoleAssignments?scope=undefined" ` -Method "OPTIONS" ` -Headers @{ "Accept"="*/*" "Access-Control-Request-Method"="GET" "Access-Control-Request-Headers"="authorization,content-type,x-ms-client-request-id,x-ms-client-session-id,x-ms-effective-locale" "Origin"="https://portal.azure.com" "User-Agent"="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36 Edg/92.0.902.84" "Sec-Fetch-Mode"="cors" "Sec-Fetch-Site"="same-site" "Sec-Fetch-Dest"="empty" "Accept-Encoding"="gzip, deflate, br" "Accept-Language"="en-US,en;q=0.9,pl;q=0.8" } #> <# GET https://admin.exchange.microsoft.com/beta/RoleGroup? HTTP/1.1 Host: admin.exchange.microsoft.com Connection: keep-alive sec-ch-ua: "Chromium";v="92", " Not A;Brand";v="99", "Microsoft Edge";v="92" x-ms-mac-hostingapp: M365AdminPortal AjaxSessionKey: x5eAwqzbVehBOP7QHfrjpwr9eYtLiHJt7TZFj0uhUMUPQ2T7yNdA7rEgOulejHDHYM1ZyCT0pgXo96EwrfVpMA== x-adminapp-request: /rbac/exchange sec-ch-ua-mobile: ?0 Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Im5PbzNaRHJPRFhFSzFqS1doWHNsSFJfS1hFZyIsImtpZCI6Im5PbzNaRHJPRFhFSzFqS1doWHNsSFJfS1hFZyJ9.eyJhdWQiOiI0OTdlZmZlOS1kZjcxLTQwNDMtYThiYi0xNGNmNzhjNGI2M2IiLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC9jZWIzNzFmNi04NzQ1LTQ4NzYtYTA0MC02OWYyZDEwYTlkMWEvIiwiaWF0IjoxNjMwMjYwMjMxLCJuYmYiOjE2MzAyNjAyMzEsImV4cCI6MTYzMDI2NDEzMSwiYWNyIjoiMSIsImFpbyI6IkFWUUFxLzhUQUFBQXBtQ1F1b2lIR3lpYTd0dFB0czFZOEpIWUpleTB1Zndzb2oycUFvSEJKWjhQclowWlJONmhQSW5BblZHRld2cXp1R0xtbXNyS1Vaak12ZVBwNDJsQXhHY0d1bk5ZNTNNMmdWbE9uSXRhcHBrPSIsImFtciI6WyJyc2EiLCJtZmEiXSwiYXBwaWQiOiIwMDAwMDAwNi0wMDAwLTBmZjEtY2UwMC0wMDAwMDAwMDAwMDAiLCJhcHBpZGFjciI6IjIiLCJkZXZpY2VpZCI6IjNhZTIyNzI2LWRmZDktNGFkNy1hODY1LWFhMmI1MWM2ZTBmZiIsImZhbWlseV9uYW1lIjoiS8WCeXMiLCJnaXZlbl9uYW1lIjoiUHJ6ZW15c8WCYXciLCJpcGFkZHIiOiI4OS43Ny4xMDIuMTciLCJuYW1lIjoiUHJ6ZW15c8WCYXcgS8WCeXMiLCJvaWQiOiJlNmE4ZjFjZi0wODc0LTQzMjMtYTEyZi0yYmY1MWJiNmRmZGQiLCJvbnByZW1fc2lkIjoiUy0xLTUtMjEtODUzNjE1OTg1LTI4NzA0NDUzMzktMzE2MzU5ODY1OS0xMTA1IiwicHVpZCI6IjEwMDMwMDAwOTQ0REI4NEQiLCJyaCI6IjAuQVM4QTluR3p6a1dIZGtpZ1FHbnkwUXFkR2dZQUFBQUFBUEVQemdBQUFBQUFBQUF2QUM4LiIsInNjcCI6InVzZXJfaW1wZXJzb25hdGlvbiIsInNpZCI6ImJkYjU3MmNiLTNkMzgtNGZlZi1iNjg2LTlmODhjNWRkNWQyNSIsInN1YiI6ImRranZjSlpIWjdjWkZPbnlSZkxZaDVLeHBUalVWdEVBLTVNSl81aF9GLWMiLCJ0aWQiOiJjZWIzNzFmNi04NzQ1LTQ4NzYtYTA0MC02OWYyZDEwYTlkMWEiLCJ1bmlxdWVfbmFtZSI6InByemVteXNsYXcua2x5c0Bldm90ZWMucGwiLCJ1cG4iOiJwcnplbXlzbGF3LmtseXNAZXZvdGVjLnBsIiwidXRpIjoiekxXUTdvUmc4ay0yVmlJV1dQNG1BQSIsInZlciI6IjEuMCIsIndpZHMiOlsiNjJlOTAzOTQtNjlmNS00MjM3LTkxOTAtMDEyMTc3MTQ1ZTEwIiwiYjc5ZmJmNGQtM2VmOS00Njg5LTgxNDMtNzZiMTk0ZTg1NTA5Il19.nzALEBEAAQBJddeeyt7Gn5sgy7y1Z1z_jfpLdjsPjgNSEOlHLPHqeyOx9QuHaEywK6es2pobYfhFtUvx1d09nz0qBI0b1wIRMX2W2-XaQOmg0FRTDQvTcC9d4Kum_hXmpTt8WgIpjKLKE0wmW8ZtsHbmh-JH3m9Y8j-9zktiRFtNbEyEa1uCTD7Wph9Ow_PAc6M9mWrERCb_XzaYDuwZWbfA_Ls2Bv8MGQsfkQh9RBsa-TgeuU1hhhGgcSaHPFAytJVQBq6QuMdqnO1pCevECf_OI2K54CcpISAUAPXW_gZXcj1waXzRRQfm85vCCh14oXvEj-Q94RsSq_5c_8cEFA client-request-id: 64d0ca10-08f4-11ec-ad6e-f9fb25a685f4 Accept: application/json, text/plain, */* x-ms-mac-version: host-mac_2021.8.19.4 x-portal-routekey: weu x-ms-mac-appid: 86d5ab1a-7f52-418c-b62d-a33841f2c949 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36 Edg/92.0.902.84 x-ms-mac-target-app: EAC Origin: https://admin.microsoft.com Sec-Fetch-Site: same-site Sec-Fetch-Mode: cors Sec-Fetch-Dest: empty Referer: https://admin.microsoft.com/ Accept-Encoding: gzip, deflate, br Accept-Language: en-US,en;q=0.9,pl;q=0.8 GET https://admin.microsoft.com/admin/api/rbac/deviceManagement/roles HTTP/1.1 Host: admin.microsoft.com Connection: keep-alive sec-ch-ua: "Chromium";v="92", " Not A;Brand";v="99", "Microsoft Edge";v="92" x-ms-mac-hostingapp: M365AdminPortal AjaxSessionKey: x5eAwqzbVehBOP7QHfrjpwr9eYtLiHJt7TZFj0uhUMUPQ2T7yNdA7rEgOulejHDHYM1ZyCT0pgXo96EwrfVpMA== x-adminapp-request: /rbac/deviceManagement sec-ch-ua-mobile: ?0 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36 Edg/92.0.902.84 Accept: application/json, text/plain, */* x-ms-mac-version: host-mac_2021.8.19.4 x-portal-routekey: weu x-ms-mac-appid: 86d5ab1a-7f52-418c-b62d-a33841f2c949 x-ms-mac-target-app: MAC Sec-Fetch-Site: same-origin Sec-Fetch-Mode: cors Sec-Fetch-Dest: empty Referer: https://admin.microsoft.com/ Accept-Encoding: gzip, deflate, br Accept-Language: en-US,en;q=0.9,pl;q=0.8 Cookie: MC1=GUID=480c128a5ba04faea7df151a53bdfa9a&HASH=480c&LV=202107&V=4&LU=1627670649689; x-portal-routekey=weu; p.BDId=00ab552e-0bd2-44f6-afb9-cbec94cb4051; s.AjaxSessionKey=x5eAwqzbVehBOP7QHfrjpwr9eYtLiHJt7TZFj0uhUMUPQ2T7yNdA7rEgOulejHDHYM1ZyCT0pgXo96EwrfVpMA%3D%3D; s.cachemap=22; s.BrowserIDe6a8f1cf-0874-4323-a12f-2bf51bb6dfdd=00ab552e-0bd2-44f6-afb9-cbec94cb4051; s.classic=False; s.CURedir=True; s.DisplayCulture=en-US; s.MFG=True; p.UtcOffset=-120; market=US; mslocale={'u':'pl-pl'}; LPVID=JjZDkxOGFjNzI3ZTFlZmY5; s.Cart={"BaseOffers":null,"Frequency":0,"IWPurchaseUserId":null,"PromotionCodes":null,"IsOfferTransition":false}; s.InNewAdmin=True; at_check=true; p.FirstLoginDateTimeUtc=id=-172832015&value=Oct_14_2015; s.ImpressionId=9c5222af-0f0a-4464-886a-ebc7eee1b188; p.FirstBillingYear=id=-172832015&value=2015; s.DefaultBillingMonth=08/20/2021 20:04:06; s.DCLoc=weuprod; p.TenantCulture=ceb371f6-8745-4876-a040-69f2d10a9d1a::pl-PL; mbox=PC#7383f384d21f43ef9a0d9d5c273578ed.37_0#1664248950|session#020faa6548144c6486e3597fd3298e30#1630064111; LPSID-60270350=HKOY_Iw3QjSJ9ijUKJt52Q; s.SessID=8798a6f9-b245-4f5e-99ed-1b78809d75a1; RootAuthToken=AwAAABoxMS8yNi8yMDIxIDE5OjA1OjU2ICswMDowMOoLMC5BUzhBOW5HenprV0hka2lnUUdueTBRcWRHZ1lBQUFBQUFQRVB6Z0FBQUFBQUFBQXZBQzguQWdBQkFBQUFBQUQtLURMQTNWTzdRcmRkZ0pnN1dldnJBZ0RzX3dRQTlQOHJfczBGMDYxZ053MTBrZllsVmtYOHZnYVZIbWFUWUVDbXltT2dzMWlGTFRsQXZ4VS1lYjdScjg2U2QwYXZSY05tNGpIcWhlMDBrYmJuWUh3NEtURnVHalN4cklQRTZjamlUUXJKYmRMMXNzcVpBVTZpUE94eVM1aHQzNEN0M1p0bWV1Y1BXaWNsZFdUNmlwVDJtT3JNS2RDaVZLUS1iRGctSHRjUjc3R094eU1hM2pIclBWOXZkOVFqdEdBY1g0azNqalZtRHJhODVFWFRKRjk3TFFEVUxGcWw1SUhyTy1ROHVfQ1RneUFjeHdjVml0anNBRllyUVFwTTFZM3hJRTFxcF9BXzZzeUZuRUFQVm9kUDIzSkUwLWtHaWNvYUowOXhRSlpvMEdTM2IwSzJtUWdFMTYybUUzRGdDQ3lna01qRjlBNko2b0otY09pZ25JOFVLNGg0MnAzVDlSeEdEbVZrTEM4LVJUbHVBUkVNS1JmTElsbFNXZVota1JHU1pZVExLY3IxUG5NN2pVSjBGZDZUODl5LTE1cFVSaWdFdHZKLTJtUms0S2s0ejUwTUtEUzIwejQzMHV3b19Ra1N6el81QnpyeFU5dnY1aGZGai1aOU5TSC16eEtKWHpaUUxua2toMElMd2NVc0xQVmdDVndPa3ZYTlRLazdNWmNUdHcyLVBOVFV2bTJha0p0ZjNQM3hIZExNX3RzdFlZUmxjVUlSOVBWWGFOeXpRTWlvX0kxU1lCanh6bUtpM2tfdVBvdXd1bzYycDltZlFOeUlrOWotX2ctQ2RlSVA4WVBsOHRnekhNMXJWTGlBWjdLUVlDZHpBNXRBMll5LVFFZEYyYi1VcDZqblFmeExoRnJBM3ZleWpRck1MUmJCdVVGVUxscUVMODZSRE16eld1eENoSGh1eEdzSTZaYnFPek9BdUJBSHpjRGxuNHN1MEpEQ3hmc3hidWhocTk4RHNHdWQ4MnhJNU1zYWtEZlZfYUN4ZXV0NzRPR1A2SnkyVGtaLVRJNWcyc2xpM2hEOW14VWRVNmVNdG1HQTVXeWs4dG9JaG1oMXVtMWNNVTBsblpFOUhOZDJKMzJHbk1LaU5Mejg4dktfeW5Va1llY2NwOEcwNUR4aUtpSGkzVUZqNm01eXFBSnVneFRTYTZ6SHBGWHF0SVFfNXZjTHJjM2JhR1paMm4xWjdBTEhZd3hxN3NSSmFNUTROZnFpRnNlT2pqR1JaNjI1VU5kdWxFTGJaLUp1aFpiS05uTG1wQlB5UkNSMEp2czlpekdRRU1ReXhhMzJKWHEzaGduQi1TcGd5N1lLS1dmYXN2MmVhV0hibUctR1hxQ2N4THZKbUV4WHM5VXVBd2NzLU1pc19wUmNzNTdlWmxHZ0xPTlpNUGxvNGQ5Vmh1b0tLanQ4dHdlRDA1VXZ5VGIzaFhjSjFBVG41aVhQampwaEFVaEhPNS01ZXg0cDkyakVmcy13SUhRV2ZURE1aZy1Ca0diVU85LUQtd0NSVExqVm1QV0k2TUFpM0h3cWxvZXZ2M3doWE80bm9NQmVMQlRsNHRiT2QyZXZocXlPaTNudHpNTzVBMFoxbzFDZ1NCMkozVkxRbFpDR2ZocHdHd1kwT3JGb25kVExIcG5LUnBLOE1YdkRLdldSd0tqUl9CSEVPU0IxNlVQOHg2SERZV1BUaGRWRDJFamVtbWpZWmgxaVF0cnZobjBFYTJiRE1yekVHcjFNTlFROGlPVENnLXlVWk1YeVVobXJYMklra05rVExZWWYzRU1ndHBGRUhDWHRTZWpueVphZ1JvcGh0M05yUTJ2MWFXOFE4Q1pfR21XcGs5dkE2MXR4MUhKZHExY3FldE1GM3FpbFAxSTJjd09RZFdNZy1OT2cA; s.LoginUserTenantId=kyHaNehhz9jpR+09ZPKS4DynUHwzw7PquEHQY+SZE6vRWhg+ZenTYDg29pApIbkUamgN9MVhZ/VbADv3Wr2Xnn3vQCRp3hHGvLU4EDcKBxLdi/J1UCSJ5YS6JobJ+hPsanTiHrdOwR5fSMI4rt1cJg==; UserIndex=H4sIAAAAAAAEAGNkYGBgBGI2IGYCsfWBBINkQVFVam5lcU5iuV52TmWxQ2pZfklqsl5BDjNQVtjIwMhQ18BC18gyxNDCysDUytSCBaSNFYTdEnOKU0HGqSSlJJmaGyUn6RqnGFvomqSlpukmmVmY6VqmWVgkm6akmKYYmYK0AQDFS8PlhAAAAA%3D%3D; OIDCAuthCookie=%2BSKNwKbOp3tUWr2%2BSTWrgME8BQoKkh7P55ishMUl3EwwalLmRnorz031%2FWXRh2gszg0uE20Nfdak8qB1vtHFOz%2FF24zwiQa0THjlt6pnBbz9vyhA4iuJNzvwt3XjSmId3Da9X8P4nQ%2FUJE%2BssHTASvNOEnPrMWvrBm1z0222f3GgiWQ2v9ArrbeXOxWvV8Me%2BUPnQ%2FEDui%2B940hO6htSDcG3h46GZJBbFSysbtE5dgQgPhixil29dQE7npcsCycLBgv%2FwypJXh%2BKq5mD%2BpfJwtNbDmvuxz9eQYZUBPWvriBHva6on%2FRXp19xAX8K%2BMwukPVYtCbqeaLP5LCK%2B1pQAFFa4GtKOY1OxVmIUcTSg88Jf0DGWYkR8CzFINgWxNhsVXRV%2BIWjz2OF6irsv%2F3L18zNFxluVlL41uzho5gqlI%2BTmgwtO%2FtWwMDqfZkdVYaufr%2B6DF6alJHFTGEb67sTmlMGeBI1w%2BeHc9Z3alFqLqcBVxg8XB88pUxzF6Dj7CGySByFC2lg%2FZaZeNgFx4BYYUa4o2rYpWhjVhYcXxixSOmFaqZhEEOCdrgB5qoTdoGMPCpoj22C9g6yow1l51GANTK9ujTRGS5LYLFA7R%2BSIcQNM50zDU1wAgoAl%2BnWQUjzK5D9XlBMhSovq7Dd4hXFW%2BnsQp2xKJL1AcE89FVKhlC3LKiwNHKSmDz2mlvYHyVRasm1jbel1BY0dKd%2F1ZMd5aKg94GEXeMdwpyyyg573HuFbCnPBd4TYdeMPg6siaMj%2Bwt%2BcZfZGbm6A9xfaq82vzUP3AU0lmz%2BYxaPT3e4fqmQVNxw0FvfPoIjy3SHaQryqseAP0LVwC6GXFOH4yEGtC63Y%2F%2FVOaE0LXbhhN10ejkQbwZGDtpUiO3%2FBihlUTVAEvYlWEnNd1Mjnr1uRl0JPknEUsbFe4gQNi7UIZo4T7vjDeNGom53bp%2BFryaNb9jCQi3jp1f9CU2xli%2B6pH%2B%2BuFvnODrDE5tJUHE3v13LljzGCbLXO%2B91K17KzIfiAoKAYnZPWNsFvgp2iUPbNRqax%2FBBtF7Zv%2ByofRex3OxXAR1kQCUcmxzItYeLBMNkTKY4B6L8w84U8Cmem%2Fnets2xdzNcYnu30qJkwHIckG7M5A4bpObrscZQ34XOiZ3%2FaLb3nAt8GhOgRe51XbzqVX86NeE9iDBhis%2FBG0JY2Ux3LZO%2B1FwKMjLO2a60OnJIRgORbjSaJV3aJiCkBlbpQ4PX5zXji41h4wSlVzYNsy2QlGJVpDfqbfqWl2DAH5JQKobBmlcp7bn3l6GGXR0XUcJJ6Qi4ZmXzofMLlc6zRhKe15cBp0zmzAlTd4%2BH6kbcduITep6h3NdjDmwFoTz96XY%2BzCE3HxgL1zrVW8qr6WYqSGbaaSqVMNKoM6Z33CRB%2BFUoVpZjHRl2kAxVdvRc3zLSI10M23PELrDur56TDDpgfi2ERY1DjNnS8BaucCs5Rqh35QQPLGmumMRprtrURFitfRlLgl7ZSyOW62ScyxxclityxBeY8NA%2Fi8IPFGrWSSrSVjAtTsJVjRUX5GHIANuZL9YImsVnrShvbyrbxMmSxfJ45pAo8mqX%2FGwnOg7V8TabzvYWuWZvUwpM%2BFktbNaQ960iRoR00UYI0IhC4hnoAAnlKeguUGq8aHuEUywllI%2FwYyjlRCXkx7znLCMj%2FuG7x7acGAStDg%2F97Q8ImojZWT9y9oD6QIPQLI7%2B4vqxBht2ZHxZMxr2WsoAUn1cB7WvPtIyJA43T36AL%2F64X0rg8Kj0nMsC3eQzoJGaWB9XSJzogLtCZAQ1W5%2BLPCIpsWL3IsL9J2gjivl%2BKNH8kDxckxpTFB69Rkau0%2BgjXXiyHEQEd6%2FDtOeRMI3MOWg%2FGzjVbVNxMJock%2B%2FpoAf%2FPgtkV8w%3D; s.DmnHQT=08/29/2021 18:06:00; s.DmnRQT=08/29/2021 18:06:07; s.DmnSOQT=08/29/2021 18:06:07; p.LastLoginDateTimeUtc=Aug_29_2021_18_06_00; MicrosoftApplicationsTelemetryDeviceId=f7e3a469-8044-4a21-ad55-69ce7f6b4086; MicrosoftApplicationsTelemetryFirstLaunchTime=2021-08-29T18:10:03.226Z #> function Get-O365AzureADRolesMember { <# .SYNOPSIS Retrieves Azure AD roles members based on specified role names or filters. .DESCRIPTION This function retrieves Azure AD roles members based on specified role names or filters. It allows querying for one or more roles at the same time and provides the flexibility to filter the results based on specific criteria. .PARAMETER RoleName Specifies the name of the role(s) to retrieve members for. .PARAMETER Filter Specifies the filter criteria to apply when retrieving role members. .PARAMETER Property Specifies the properties to include in the results. .PARAMETER OrderBy Specifies the order in which the results should be sorted. .PARAMETER All Indicates whether all roles should be retrieved. .EXAMPLE Get-O365AzureADRolesMember -RoleName "Role1", "Role2" -Property "Property1", "Property2" -OrderBy "Property1" -All Retrieves members for specified roles with specific properties and sorting order. .EXAMPLE Get-O365AzureADRolesMember -Filter "FilterCriteria" Retrieves members based on the specified filter criteria. #> [cmdletBinding(DefaultParameterSetName = 'Role')] param( [Parameter(Mandatory, ParameterSetName = 'Role')][Array] $RoleName, [Parameter(ParameterSetName = 'Filter')][string] $Filter, [Parameter(ParameterSetName = 'Role')] [Parameter(ParameterSetName = 'Filter')] [Parameter(ParameterSetName = 'All')] [string[]] $Property, [Parameter(ParameterSetName = 'Role')] [Parameter(ParameterSetName = 'Filter')] [Parameter(ParameterSetName = 'All')] [string] $OrderBy, [Parameter(ParameterSetName = 'All')][switch] $All ) $Uri = "https://graph.microsoft.com/v1.0/roleManagement/directory/roleAssignments" $QueryParameter = @{ '$Select' = $Property -join ',' '$orderby' = $OrderBy } $RolesList = [ordered] @{} if ($RoleName -or $All) { # in case user wanted all roles, we get it to him if ($All) { # we either use cache, or we ask for it if (-not $Script:AzureADRoles) { $RoleName = (Get-O365AzureADRoles).displayName } else { $RoleName = $Script:AzureADRoles.displayName } } # We want to get one or more roles at the same time foreach ($Role in $RoleName) { $RoleID = $null # We find the ID based on the cache or we ask Graph API to provide the list the first time if ($Script:AzureADRolesListReverse) { $TranslatedRole = $Script:AzureADRolesListReverse[$Role] } else { $null = Get-O365AzureADRoles $TranslatedRole = $Script:AzureADRolesListReverse[$Role] } if ($TranslatedRole) { # Once we have ID we query graph API $RoleID = $TranslatedRole.id $QueryParameter['$filter'] = "roleDefinitionId eq '$RoleID'" } else { Write-Warning -Message "Get-O365AzureADRolesMember - Couldn't gather roles because the ID translation didn't work for $Role" continue } Remove-EmptyValue -Hashtable $QueryParameter # We query graph API Write-Verbose -Message "Get-O365AzureADRolesMember - requesting role $Role ($RoleID)" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -QueryParameter $QueryParameter -Method GET # if we asked for just one role we return the results directly if ($RoleName.Count -eq 1) { Write-Verbose -Message "Get-O365AzureADRolesMember - requesting users for $Role ($RoleID)" foreach ($User in $Output) { Get-O365PrivateUserOrSPN -PrincipalID $User.principalId } } else { # if we asked for more than one role we add the results to the list Write-Verbose -Message "Get-O365AzureADRolesMember - requesting users for $Role ($RoleID)" $RolesList[$Role] = foreach ($User in $Output) { Get-O365PrivateUserOrSPN -PrincipalID $User.principalId } } } if ($RoleName.Count -gt 1) { # if we asked for more than one role we return the list $RolesList } } elseif ($Filter) { $QueryParameter['$filter'] = $Filter Remove-EmptyValue -Hashtable $QueryParameter $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -QueryParameter $QueryParameter -Method GET foreach ($User in $Output) { Get-O365PrivateUserOrSPN -PrincipalID $User.principalId } } } $Script:AzureRolesScriptBlock = { param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters) #Convert-AzureRole -All | Where-Object { $_ -like "*$wordToComplete*" } if (-not $Script:AzureADRoles) { $AzureRoles = Get-O365AzureADRoles } else { $AzureRoles = $Script:AzureADRoles } ($AzureRoles | Where-Object { $_.displayName -like "*$wordToComplete*" }).displayName } Register-ArgumentCompleter -CommandName Get-O365AzureADRolesMember -ParameterName RoleName -ScriptBlock $Script:AzureRolesScriptBlock <# https://graph.microsoft.com/beta/roleManagement/directory/roleAssignments&$filter=roleDefinitionId eq ‘<object-id-or-template-id-of-role-definition>’ #> #https://graph.microsoft.com/beta/roleManagement/directory/roleAssignments&$filter=roleDefinitionId eq ‘<object-id-or-template-id-of-role-definition>’ #$Uri = 'https://main.iam.ad.ext.azure.com/api/Roles/User/e6a8f1cf-0874-4323-a12f-2bf51bb6dfdd/RoleAssignments?scope=undefined' <# GET https://graph.microsoft.com/beta/rolemanagement/directory/roleAssignments?$filter=principalId eq '55c07278-7109-4a46-ae60-4b644bc83a31' GET https://graph.microsoft.com/beta/groups?$filter=displayName+eq+'Contoso_Helpdesk_Administrator' GET https://graph.microsoft.com/beta/roleManagement/directory/roleAssignments?$filter=principalId eq #> <# Invoke-WebRequest -Uri "https://api.azrbac.mspim.azure.com/api/v2/privilegedAccess/aadroles/roleAssignments?`$expand=linkedEligibleRoleAssignment,subject,scopedResource,roleDefinition(`$expand=resource)&`$count=true&`$filter=(roleDefinition/resource/id%20eq%20%27ceb371f6-8745-4876-a040-69f2d10a9d1a%27)+and+(roleDefinition/id%20eq%20%275d6b6bb7-de71-4623-b4af-96380a352509%27)+and+(assignmentState%20eq%20%27Eligible%27)&`$orderby=roleDefinition/displayName&`$skip=0&`$top=10" -Headers @{ "x-ms-client-session-id"="3049c4c42d944f68bb7423154f7a1da5" "Accept-Language"="en" "Authorization"="Bearer ." "x-ms-effective-locale"="en.en-us" "Accept"="application/json, text/javascript, */*; q=0.01" #"Referer"="" "x-ms-client-request-id"="b0a543fc-ca4c-4ac6-aef6-5ceb09ad9003" "User-Agent"="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36 Edg/92.0.902.84" } #> function Get-O365AzureConditionalAccess { <# .SYNOPSIS Retrieves Azure Conditional Access policies. .DESCRIPTION This function retrieves Azure Conditional Access policies based on the provided headers. It returns a list of policies with their details, including policy ID, name, apply rule, state, use policy state, baseline type, creation date, and modification date. If the -Details switch is used, it retrieves detailed information about each policy. .PARAMETER Headers A dictionary containing the headers for the API request, typically including authorization information. .PARAMETER Details A switch parameter to indicate if detailed information about each policy is required. .EXAMPLE Get-O365AzureConditionalAccess -Headers $headers Get-O365AzureConditionalAccess -Headers $headers -Details .NOTES For more information, visit: https://docs.microsoft.com/en-us/azure/active-directory/conditional-access/overview #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [switch] $Details ) #$Uri = 'https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies' # Need to figure out scopes and use graph instead. But till then... #$Uri = 'https://main.iam.ad.ext.azure.com/api/Policies/Policies?top=10&nextLink=null&appId=&includeBaseline=true' # "https://main.iam.ad.ext.azure.com/api/Policies/7eac83fb-856b-45bf-9896-4fc78ea686f1" # move it later on $Script:O365PolicyState = @{ '2' = 'Report-only' '1' = 'Off' '0' = 'On' # i think } $QueryParameters = @{ top = 10 nextLink = $null #appID = '' includeBaseline = $true } $Uri = 'https://main.iam.ad.ext.azure.com/api/Policies/Policies' $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -QueryParameter $QueryParameters if ($Output.items) { foreach ($Policy in $Output.items) { if (-not $Details) { [PSCustomObject] @{ PolicyId = $Policy.policyId #: 7eac83fb-856b-45bf-9896-4fc78ea686f1 PolicyName = $Policy.policyName #: Guest Access Policy 1 ApplyRule = $Policy.applyRule #: False PolicyState = $O365PolicyState[$Policy.policyState.ToString()] #: 1 UsePolicyState = $Policy.usePolicyState #: True BaselineType = $Policy.baselineType #: 0 CreatedDate = $Policy.createdDateTime #: 11.09.2021 09:02:21 ModifiedDate = $Policy.modifiedDateTime #: 11.09.2021 17:38:21 } } else { $PolicyDetails = Get-O365AzureConditionalAccessPolicy -PolicyID $Policy.policyId if ($PolicyDetails) { $PolicyDetails } } } } } function Get-O365AzureConditionalAccessClassic { <# .SYNOPSIS Retrieves classic Azure Conditional Access policies. .DESCRIPTION This function retrieves classic Azure Conditional Access policies based on the provided headers. It returns information about the classic policies, including their state, users, service principals, controls, and more. .PARAMETER Headers A dictionary containing the headers for the API request, typically including authorization information. .EXAMPLE Get-O365AzureConditionalAccessClassic -Headers $headers .NOTES For more information, visit: https://docs.microsoft.com/en-us/azure/active-directory/conditional-access/overview #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = 'https://main.iam.ad.ext.azure.com/api/ClassicPolicies' $QueryParameters = @{ top = 10 nextLink = $null filter = 1 } $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -QueryParameter $QueryParameters if ($Output.items) { $Output.items } } function Get-O365AzureConditionalAccessLocation { <# .SYNOPSIS Retrieves Azure Conditional Access Locations. .DESCRIPTION This function retrieves Azure Conditional Access Locations based on the provided headers. It returns information about the named locations defined for Azure Conditional Access policies. .PARAMETER Headers A dictionary containing the headers for the API request, typically including authorization information. .EXAMPLE Get-O365AzureConditionalAccessLocation -Headers $headers .NOTES For more information, visit: https://docs.microsoft.com/en-us/azure/active-directory/conditional-access/overview #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = 'https://graph.microsoft.com/beta/conditionalAccess/namedLocations' #?`$filter=&`$orderby=displayName&`$skip=0&`$top=10&`$count=true $QueryParameters = @{ top = 10 skip = 0 orderby = 'displayName' filter = '' count = 'true' } $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -QueryParameter $QueryParameters if ($Output) { $Output } } function Get-O365AzureConditionalAccessPolicy { <# .SYNOPSIS Retrieves Azure Conditional Access Policy details. .DESCRIPTION This function retrieves Azure Conditional Access Policy details based on the provided policy ID or name. It returns detailed information about the policy, including its state, users, service principals, controls, and more. .PARAMETER Headers A dictionary containing the headers for the API request, typically including authorization information. .PARAMETER PolicyID The unique identifier of the policy to retrieve. .PARAMETER PolicyName The name of the policy to retrieve. .EXAMPLE Get-O365AzureConditionalAccessPolicy -PolicyID '7eac83fb-856b-45bf-9896-4fc78ea686f1' -Headers $headers Get-O365AzureConditionalAccessPolicy -PolicyName 'Guest Access Policy 1' -Headers $headers .NOTES For more information, visit: https://docs.microsoft.com/en-us/azure/active-directory/conditional-access/overview #> [cmdletbinding()] param( [parameter(ParameterSetName = 'PolicyID')] [parameter(ParameterSetName = 'PolicyName')] [alias('Authorization')][System.Collections.IDictionary] $Headers, [parameter(Mandatory, ParameterSetName = 'PolicyID')][string] $PolicyID, [parameter(Mandatory, ParameterSetName = 'PolicyName')][string] $PolicyName ) # move it later on $Script:O365PolicyState = @{ '2' = 'Report-only' '1' = 'Off' '0' = 'On' # i think } if ($PolicyID) { $Uri = "https://main.iam.ad.ext.azure.com/api/Policies/$PolicyID" } elseif ($PolicyName) { $FoundPolicy = $null $Policies = Get-O365AzureConditionalAccess -Headers $Headers foreach ($Policy in $Policies) { if ($Policy.policyName -eq $PolicyName) { $FoundPolicy = $Policy.policyId break } } if ($null -ne $FoundPolicy) { $Uri = "https://main.iam.ad.ext.azure.com/api/Policies/$FoundPolicy" } else { Write-Warning -Message "Get-O365AzureConditionalAccessPolicy - No policy with name $PolicyName" return } } else { Write-Warning -Message "Get-O365AzureConditionalAccessPolicy - No policy ID or name specified" return } $PolicyDetails = Invoke-O365Admin -Uri $Uri -Headers $Headers #-QueryParameter $QueryParameters if ($PolicyDetails) { [PSCustomObject] @{ PolicyId = $PolicyDetails.policyId #: 7eac83fb-856b-45bf-9896-4fc78ea686f1 PolicyName = $PolicyDetails.policyName #: Guest Access Policy 1 ApplyRule = $PolicyDetails.applyRule #: False PolicyState = $Script:O365PolicyState[$PolicyDetails.policyState.ToString()] #: 1 UsePolicyState = $PolicyDetails.usePolicyState #: True BaselineType = $PolicyDetails.baselineType #: 0 CreatedDate = $PolicyDetails.createdDateTime #: 11.09.2021 09:02:21 ModifiedDate = $PolicyDetails.modifiedDateTime #: 11.09.2021 17:38:21 #users = $PolicyDetails.users # # : @{allUsers=2; included=; excluded=} Users = $PolicyDetails.usersV2 # # : @{allUsers=2; included=; excluded=} #servicePrincipals = $PolicyDetails.servicePrincipals # # : @{allServicePrincipals=1; included=; excluded=; filter=; includeAllMicrosoftApps=False; excludeAllMicrosoftApps=False; userActions=; stepUpTags=} ServicePrincipals = $PolicyDetails.servicePrincipalsV2 # # : @{allServicePrincipals=1; included=; excluded=; filter=; includedAppContext=; shouldIncludeAppContext=False} controls = $PolicyDetails.controls # # : @{controlsOr=True; blockAccess=False; challengeWithMfa=True; compliantDevice=False; domainJoinedDevice=False; approvedClientApp=False; claimProviderControlIds=System.Object[]; requireCompliantApp=False; requirePasswordChange=False; requiredFederatedAuthMethod=0} sessionControls = $PolicyDetails.sessionControls # # : @{appEnforced=False; cas=False; cloudAppSecuritySessionControlType=0; signInFrequencyTimeSpan=; signInFrequency=0; persistentBrowserSessionMode=0; continuousAccessEvaluation=0; resiliencyDefaults=0; secureSignIn=False} conditions = $PolicyDetails.conditions # # : @{minUserRisk=; minSigninRisk=; devicePlatforms=; locations=; namedNetworks=; clientApps=; clientAppsV2=; time=; deviceState=} clientApplications = $PolicyDetails.clientApplications # # : @{allServicePrincipals=0; filter=; includedServicePrincipals=; excludedServicePrincipals=} isAllProtocolsEnabled = $PolicyDetails.isAllProtocolsEnabled # # : False isUsersGroupsV2Enabled = $PolicyDetails.isUsersGroupsV2Enabled # # : False isCloudAppsV2Enabled = $PolicyDetails.isCloudAppsV2Enabled # # : False version = $PolicyDetails.version # # : 1 isFallbackUsed = $PolicyDetails.isFallbackUsed # # : False } } } function Get-O365AzureConditionalAccessTerms { <# .SYNOPSIS Retrieves Azure Conditional Access Terms. .DESCRIPTION This function retrieves Azure Conditional Access Terms based on the provided headers. It returns information about the terms of use agreements for Azure Conditional Access. .PARAMETER Headers A dictionary containing the headers for the API request, typically including authorization information. .EXAMPLE Get-O365AzureConditionalAccessTerms -Headers $headers .NOTES For more information, visit: https://docs.microsoft.com/en-us/azure/active-directory/conditional-access/overview #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) # ?`$orderby=Name%20asc&`$filter=TypeId%20eq%208a76863a-a0e6-47a7-b99e-0410266eebcf # &x-tenantid=ceb371f6-8745-4876-a040-69f2d10a9d1a&{}&_=1631363067293 $Uri = 'https://api.termsofuse.identitygovernance.azure.com/v1.1/Agreements' $QueryParameter = @{ '$orderby' = 'Name asc' '$filter' = 'TypeId eq 8a76863a-a0e6-47a7-b99e-0410266eebcf' 'x-tenantid' = $TenantID } $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers if ($Output) { $Output } } function Get-O365AzureConditionalAccessVPN { <# .SYNOPSIS Retrieves VPN certificates for Azure Conditional Access. .DESCRIPTION This function retrieves VPN certificates for Azure Conditional Access based on the provided headers. .PARAMETER Headers A dictionary containing the headers for the API request, typically including authorization information. .EXAMPLE Get-O365AzureConditionalAccessVPN -Headers $headers .NOTES For more information, visit: - https://docs.microsoft.com/en-us/azure/active-directory/manage-apps/configure-user-consent?tabs=azure-portal - https://portal.azure.com/#blade/Microsoft_AAD_IAM/ConsentPoliciesMenuBlade/UserSettings - https://portal.azure.com/#blade/Microsoft_AAD_IAM/StartboardApplicationsMenuBlade/UserSettings/menuId/ #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = 'https://main.iam.ad.ext.azure.com/api/Vpn/Certificates' $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers if ($Output) { $Output } } function Get-O365AzureEnterpriseAppsGroupConsent { <# .SYNOPSIS Retrieves the group consent settings for Azure Enterprise Apps. .DESCRIPTION This function retrieves the group consent settings for Azure Enterprise Apps from the Microsoft Graph API. It returns the specific consent settings for the group. .PARAMETER Headers A dictionary containing the headers for the API request, typically including authorization information. .PARAMETER NoTranslation Specifies whether to return the consent settings without translation. .EXAMPLE Get-O365AzureEnterpriseAppsGroupConsent -Headers $headers .NOTES For more information, visit: https://docs.microsoft.com/en-us/azure/active-directory/manage-apps/configure-user-consent?tabs=azure-portal #> # https://docs.microsoft.com/en-us/azure/active-directory/manage-apps/configure-user-consent?tabs=azure-portal [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [switch] $NoTranslation ) $Uri = 'https://graph.microsoft.com/beta/settings' $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers if ($Output) { if ($NoTranslation) { ($Output | Where-Object { $_.displayName -eq 'Consent Policy Settings' }).values } else { $ConsentPolicy = $Output | Where-Object { $_.displayName -eq 'Consent Policy Settings' } if ($ConsentPolicy) { $Object = [PSCustomObject] @{ EnableGroupSpecificConsent = ($ConsentPolicy.values | Where-Object { $_.name -eq 'EnableGroupSpecificConsent' } | Select-Object -ExpandProperty value) BlockUserConsentForRiskyApps = $ConsentPolicy.values | Where-Object { $_.name -eq 'BlockUserConsentForRiskyApps' } | Select-Object -ExpandProperty value EnableAdminConsentRequests = $ConsentPolicy.values | Where-Object { $_.name -eq 'EnableAdminConsentRequests' } | Select-Object -ExpandProperty value ConstrainGroupSpecificConsentToMembersOfGroupId = $ConsentPolicy.values | Where-Object { $_.name -eq 'ConstrainGroupSpecificConsentToMembersOfGroupId' } | Select-Object -ExpandProperty value } if ($Object.EnableGroupSpecificConsent -eq 'true') { $Object.EnableGroupSpecificConsent = $true } else { $Object.EnableGroupSpecificConsent = $false } if ($Object.BlockUserConsentForRiskyApps -eq 'true') { $Object.BlockUserConsentForRiskyApps = $true } else { $Object.BlockUserConsentForRiskyApps = $false } if ($Object.EnableAdminConsentRequests -eq 'true') { $Object.EnableAdminConsentRequests = $true } else { $Object.EnableAdminConsentRequests = $false } $Object } } } } function Get-O365AzureEnterpriseAppsUserConsent { <# .SYNOPSIS Retrieves user consent settings for Azure Enterprise Apps. .DESCRIPTION This function retrieves user consent settings for Azure Enterprise Apps based on the provided headers. It returns information about permissions and policies assigned to users. .PARAMETER Headers A dictionary containing the headers for the API request, typically including authorization information. .PARAMETER NoTranslation Specifies whether to return the consent settings without translation. .EXAMPLE Get-O365AzureEnterpriseAppsUserConsent -Headers $headers .NOTES For more information, visit: https://docs.microsoft.com/en-us/azure/active-directory/manage-apps/configure-user-consent?tabs=azure-portal #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [switch] $NoTranslation ) # https://docs.microsoft.com/en-us/azure/active-directory/manage-apps/configure-user-consent?tabs=azure-portal # https://portal.azure.com/#blade/Microsoft_AAD_IAM/ConsentPoliciesMenuBlade/UserSettings $Uri = 'https://graph.microsoft.com/v1.0/policies/authorizationPolicy?$select=defaultUserRolePermissions' $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers if ($Output) { if ($NoTranslation) { $Output } else { [PSCustomObject] @{ allowedToCreateApps = $Output.defaultUserRolePermissions.allowedToCreateApps allowedToCreateSecurityGroups = $Output.defaultUserRolePermissions.allowedToCreateSecurityGroups allowedToReadOtherUsers = $Output.defaultUserRolePermissions.allowedToReadOtherUsers permissionGrantPoliciesAssigned = Convert-AzureEnterpriseAppsUserConsent -PermissionsGrantPoliciesAssigned $Output.defaultUserRolePermissions.permissionGrantPoliciesAssigned } } } } function Get-O365AzureEnterpriseAppsUserSettings { <# .SYNOPSIS Retrieves user settings for Azure Enterprise Apps. .DESCRIPTION This function retrieves user settings for Azure Enterprise Apps based on the provided headers. It returns information about user consent settings for accessing data, adding gallery apps, and visibility of Office 365 apps in the portal. .PARAMETER Headers A dictionary containing the headers for the API request, typically including authorization information. .PARAMETER NoTranslation Specifies whether to return the user settings without translation. .EXAMPLE Get-O365AzureEnterpriseAppsUserSettings -Headers $headers .NOTES For more information, visit: https://docs.microsoft.com/en-us/azure/active-directory/manage-apps/configure-user-consent?tabs=azure-portal #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [switch] $NoTranslation ) # https://docs.microsoft.com/en-us/azure/active-directory/manage-apps/configure-user-consent?tabs=azure-portal # https://portal.azure.com/#blade/Microsoft_AAD_IAM/ConsentPoliciesMenuBlade/UserSettings # https://portal.azure.com/#blade/Microsoft_AAD_IAM/StartboardApplicationsMenuBlade/UserSettings/menuId/ $Uri = 'https://main.iam.ad.ext.azure.com/api/EnterpriseApplications/UserSettings' $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers if ($Output) { if ($NoTranslation) { $Output } else { [PSCustomObject] @{ UsersCanConsentAppsAccessingData = $Output.usersCanAllowAppsToAccessData UsersCanAddGalleryAppsToMyApp = $Output.usersCanAddGalleryApps UsersCanOnlySeeO365AppsInPortal = $Output.hideOffice365Apps } } } } function Get-O365AzureEnterpriseAppsUserSettingsAdmin { <# .SYNOPSIS Retrieves user settings for Azure Enterprise Apps with admin consent flow. .DESCRIPTION This function retrieves user settings for Azure Enterprise Apps with admin consent flow based on the provided headers. It returns information about request expiration days, notifications, reminders, approvers, and approversV2. .PARAMETER Headers A dictionary containing the headers for the API request, typically including authorization information. .PARAMETER NoTranslation Specifies whether to return the user settings without translation. .EXAMPLE Get-O365AzureEnterpriseAppsUserSettingsAdmin -Headers $headers .NOTES For more information, visit: https://docs.microsoft.com/en-us/azure/active-directory/manage-apps/configure-user-consent?tabs=azure-portal #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [switch] $NoTranslation ) # https://docs.microsoft.com/en-us/azure/active-directory/manage-apps/configure-user-consent?tabs=azure-portal # https://portal.azure.com/#blade/Microsoft_AAD_IAM/ConsentPoliciesMenuBlade/UserSettings # https://portal.azure.com/#blade/Microsoft_AAD_IAM/StartboardApplicationsMenuBlade/UserSettings/menuId/ $Uri = 'https://main.iam.ad.ext.azure.com/api/RequestApprovals/V2/PolicyTemplates?type=AdminConsentFlow' $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers if ($Output) { if ($NoTranslation) { $Output } else { [PSCustomObject] @{ requestExpiresInDays = $Output.requestExpiresInDays notificationsEnabled = $Output.notificationsEnabled remindersEnabled = $Output.remindersEnabled approvers = $Output.approvers approversV2 = $Output.approversV2 } } } } function Get-O365AzureEnterpriseAppsUserSettingsPromoted { <# .SYNOPSIS Retrieves user settings for promoted Azure Enterprise Apps. .DESCRIPTION This function retrieves user settings for promoted Azure Enterprise Apps based on the provided headers. .PARAMETER Headers A dictionary containing the headers for the API request, typically including authorization information. .EXAMPLE Get-O365AzureEnterpriseAppsUserSettingsPromoted -Headers $headers .NOTES For more information, visit: - https://docs.microsoft.com/en-us/azure/active-directory/manage-apps/configure-user-consent?tabs=azure-portal - https://portal.azure.com/#blade/Microsoft_AAD_IAM/ConsentPoliciesMenuBlade/UserSettings - https://portal.azure.com/#blade/Microsoft_AAD_IAM/StartboardApplicationsMenuBlade/UserSettings/menuId/ #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) # https://docs.microsoft.com/en-us/azure/active-directory/manage-apps/configure-user-consent?tabs=azure-portal # https://portal.azure.com/#blade/Microsoft_AAD_IAM/ConsentPoliciesMenuBlade/UserSettings # https://portal.azure.com/#blade/Microsoft_AAD_IAM/StartboardApplicationsMenuBlade/UserSettings/menuId/ $Uri = 'https://main.iam.ad.ext.azure.com/api/workspaces/promotedapps' $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers $Output } function Get-O365AzureExternalCollaborationFlows { <# .SYNOPSIS Provides information about Azure external collaboration flows. .DESCRIPTION This function retrieves details about Azure external collaboration flows based on the provided headers. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .EXAMPLE Get-O365AzureExternalCollaborationFlows -Headers $headers .NOTES WARNING: Invoke-O365Admin - Error JSON: Response status code does not indicate success: 403 (Forbidden). The application does not have any of the required delegated permissions (Policy.Read.All, Policy.ReadWrite.AuthenticationFlows) to access the resource. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = 'https://graph.microsoft.com/v1.0/policies/authenticationFlowsPolicy' $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers $Output } function Get-O365AzureExternalCollaborationRestrictions { <# .SYNOPSIS Retrieves Azure external collaboration restrictions based on the provided headers. .DESCRIPTION This function retrieves Azure external collaboration restrictions from the specified API endpoint using the provided headers. It can also translate the output into a more readable format if the -NoTranslation switch is not used. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .PARAMETER NoTranslation A switch parameter to indicate whether to skip translation of the output. If used, the raw output will be returned without any additional processing. .EXAMPLE Get-O365AzureExternalCollaborationRestrictions -Headers $headers -NoTranslation .NOTES This function is designed to work in conjunction with Connect-O365Admin to fetch the necessary headers for authentication. It retrieves the Azure external collaboration restrictions, which include settings and configurations related to external collaboration. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [switch] $NoTranslation ) $Uri = 'https://main.iam.ad.ext.azure.com/api/B2B/b2bPolicy' $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers if ($Output) { if ($NoTranslation) { $Output <# targetedDomains : {} hasListEntries : True isAllowlist : False otpEnabled : False adminConsentedForUsersIntoTenantIds : {} noAADConsentForUsersFromTenantsIds : {} #> } else { if ($Output.isAllowlist -eq $true -and $Output.targetedDomains.count -eq 0) { $CollaborationRestrictions = 'AllowAnyDomain' } elseif ($Output.isAllowlist -eq $true -and $Output.targetedDomains.count -gt 0) { $CollaborationRestrictions = 'AllowSpecifiedDomains' } elseif ($Output.isAllowlist -eq $false -and $Output.targetedDomains.count -eq 0) { # Won't really happen as microsoft doesn't allow to to have 0 domains for allowed domains $CollaborationRestrictions = 'DisallowAnyDomain' } elseif ($Output.isAllowlist -eq $false -and $Output.targetedDomains.count -gt 0) { $CollaborationRestrictions = 'DisallowSpecifiedDomains' } else { # Won't really happen $CollaborationRestrictions = 'Unknown' } [PSCustomObject] @{ CollaborationRestrictions = $CollaborationRestrictions TargetedDomains = $Output.targetedDomains # #hasListEntries = $Output.hasListEntries # : True #isAllowlist = $Output.isAllowlist # : False #otpEnabled = $Output.otpEnabled # : False #adminConsentedForUsersIntoTenantIds = $Output.adminConsentedForUsersIntoTenantIds # : {} #noAADConsentForUsersFromTenantsIds = $Output.noAADConsentForUsersFromTenantsIds # : {} # : } } } } function Get-O365AzureExternalCollaborationSettings { <# .SYNOPSIS Retrieves Azure external collaboration settings based on the provided headers. .DESCRIPTION This function retrieves Azure external collaboration settings from the specified API endpoint using the provided headers. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $ReverseGuestRole = @{ 'a0b1b346-4d3e-4e8b-98f8-753987be4970' = 'User' '10dae51f-b6af-4016-8d66-8c2a99b929b3' = 'GuestUser' '2af84b1e-32c8-42b7-82bc-daa82404023b' = 'RestrictedUser' } $Uri = 'https://graph.microsoft.com/v1.0/policies/authorizationPolicy' $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers if ($Output) { [PSCustomObject] @{ #id = $Output.id # : authorizationPolicy allowInvitesFrom = $Output.allowInvitesFrom # : adminsAndGuestInviters allowedToSignUpEmailBasedSubscriptions = $Output.allowedToSignUpEmailBasedSubscriptions # : True allowedToUseSSPR = $Output.allowedToUseSSPR # : True allowEmailVerifiedUsersToJoinOrganization = $Output.allowEmailVerifiedUsersToJoinOrganization # : False blockMsolPowerShell = $Output.blockMsolPowerShell # : False displayName = $Output.displayName # : Authorization Policy description = $Output.description # : Used to manage authorization related settings across the company. guestUserRoleId = $ReverseGuestRole[$Output.guestUserRoleId] # : a0b1b346-4d3e-4e8b-98f8-753987be4970 defaultUserRolePermissions = $Output.defaultUserRolePermissions # : } } } <# $o = Invoke-WebRequest -Uri "https://graph.microsoft.com/beta/policies/authenticationFlowsPolicy" -Headers @{ "x-ms-client-session-id" = "a2f6c5f9b1b8450dbb0116f95ffbe9b2" "Accept-Language" = "en" "Authorization" = "Bearer . "x-ms-effective-locale" = "en.en-us" "Accept" = "*/*" #"Referer"="" "x-ms-client-request-id" = "d4bc027d-339c-46c2-ba96-c07f53fc5002" "User-Agent" = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36 Edg/92.0.902.84" } $o.content $p = Invoke-WebRequest -Uri "https://graph.microsoft.com/beta/policies/authorizationPolicy" -Headers @{ "x-ms-client-session-id" = "a2f6c5f9b1b8450dbb0116f95ffbe9b2" "Accept-Language" = "en" "Authorization" = "Bearer .. "x-ms-effective-locale" = "en.en-us" "Accept" = "*/*" #"Referer" = "" "x-ms-client-request-id" = "d4bc027d-339c-46c2-ba96-c07f53fc5001" "User-Agent" = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36 Edg/92.0.902.84" } $p.COntent $g = Invoke-WebRequest -Uri "https://main.iam.ad.ext.azure.com/api/B2B/b2bPolicy" ` -Headers @{ "x-ms-client-session-id" = "02ca6867073543de9a89b767ad581135" "Accept-Language" = "en" "Authorization" = "Bearer " "x-ms-effective-locale" = "en.en-us" "Accept" = "*/*" #"Referer" = "" "User-Agent" = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36 Edg/92.0.902.84" "x-ms-client-request-id" = "cf957d13-fc12-415d-a86a-1d74507d9003" } ` -ContentType "application/json" $g.content #> function Get-O365AzureExternalIdentitiesEmail { <# .SYNOPSIS Provides functionality to retrieve email authentication method configurations for external identities in Office 365. .DESCRIPTION This function retrieves email authentication method configurations for external identities in Office 365 from the specified API endpoint using the provided headers. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .PARAMETER NoTranslation A switch parameter to indicate whether to skip translation of the output. .EXAMPLE Get-O365AzureExternalIdentitiesEmail -Headers $headers -NoTranslation #> # https://portal.azure.com/#blade/Microsoft_AAD_IAM/CompanyRelationshipsMenuBlade/IdentityProviders [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [switch] $NoTranslation ) $Uri = 'https://graph.microsoft.com/beta/policies/authenticationmethodspolicy/authenticationMethodConfigurations/email' $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers if ($Output) { if ($NoTranslation) { $Output } else { $Output } } } <# Requires scp : AccessReview.ReadWrite.All AuditLog.Read.All Directory.AccessAsUser.All Directory.Read.All Directory.ReadWrite.All email EntitlementManagement.Read.All Group.ReadWrite.All IdentityProvider.ReadWrite.All IdentityRiskEvent.ReadWri te.All IdentityUserFlow.Read.All openid Policy.Read.All Policy.ReadWrite.AuthenticationFlows Policy.ReadWrite.AuthenticationMethod Policy.ReadWrite.ConditionalAccess profile Reports.Read.All RoleManagement.ReadWrite.Directory Se curityEvents.ReadWrite.All TrustFrameworkKeySet.Read.All User.Export.All User.ReadWrite.All UserAuthenticationMethod.ReadWrite.All #> function Get-O365AzureExternalIdentitiesPolicies { <# .SYNOPSIS Retrieves Azure external identities policies from the specified endpoint. .DESCRIPTION This function retrieves Azure external identities policies from the specified API endpoint using the provided headers. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .PARAMETER NoTranslation A switch parameter to indicate whether to skip translation of the output. .EXAMPLE Get-O365AzureExternalIdentitiesPolicies -Headers $headers -NoTranslation #> # https://portal.azure.com/#blade/Microsoft_AAD_IAM/CompanyRelationshipsMenuBlade/IdentityProviders [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [switch] $NoTranslation ) $Uri = 'https://main.iam.ad.ext.azure.com/api/B2B/b2bPolicy' $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers if ($Output) { if ($NoTranslation) { $Output } else { $Output } } } function Get-O365AzureFeatureConfiguration { <# .SYNOPSIS Retrieves Azure feature configuration information. .DESCRIPTION This function fetches the Azure feature configuration information using the provided headers or attempts to fetch them from the current execution context if not provided. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. If not provided, the function will attempt to fetch it from the current execution context. .EXAMPLE Get-O365AzureFeatureConfiguration -Headers $headers .NOTES This function is designed to work in conjunction with Connect-O365Admin to fetch the necessary headers for authentication. It retrieves the Azure feature configuration information, which includes various settings and configurations. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = 'https://main.iam.ad.ext.azure.com/api/FeatureConfigurations?supportAU=false' $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers if ($Output) { $Output } } function Get-O365AzureFeaturePortal { <# .SYNOPSIS Retrieves the Azure feature portal information. .DESCRIPTION This function fetches the Azure feature portal information using the provided headers or attempts to fetch them from the current execution context if not provided. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. If not provided, the function will attempt to fetch it from the current execution context. .EXAMPLE Get-O365AzureFeaturePortal -Headers $headers .NOTES This function is designed to work in conjunction with Connect-O365Admin to fetch the necessary headers for authentication. It retrieves the Azure feature portal information, which includes various settings and configurations. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = 'https://afd.hosting.portal.azure.net/iam/?bundlingKind=DefaultPartitioner&cacheability=3&clientOptimizations=true&environmentjson=true&extensionName=Microsoft_AAD_IAM&l=en&pageVersion=3.0.01692206&trustedAuthority=portal.azure.com' $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers if ($Output) { $Output } } function Get-O365AzureGroupExpiration { <# .SYNOPSIS Retrieves Azure group expiration information from the specified endpoint. .DESCRIPTION This function retrieves Azure group expiration information from the specified API endpoint using the provided headers. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .PARAMETER NoTranslation A switch parameter to indicate whether to skip translation of the output. .EXAMPLE Get-O365AzureGroupExpiration -Headers $headers -NoTranslation #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [switch] $NoTranslation ) $Uri = 'https://main.iam.ad.ext.azure.com/api/Directories/LcmSettings' $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method Get if ($Output) { if ($NoTranslation) { $Output } else { if ($Output.expiresAfterInDays -eq 0) { $GroupLifeTime = '180' } elseif ($Output.expiresAfterInDays -eq 1) { $GroupLifeTime = '365' } elseif ($Output.expiresAfterInDays -eq 2) { $GroupLifeTime = $Output.groupLifetimeCustomValueInDays } if ($Output.managedGroupTypes -eq 2) { $ExpirationEnabled = 'None' } elseif ($Output.managedGroupTypes -eq 1) { $ExpirationEnabled = 'Selected' } elseif ($Output.managedGroupTypes -eq 0) { $ExpirationEnabled = 'All' } else { $ExpirationEnabled = 'Unknown' } <# expiresAfterInDays : 2 groupLifetimeCustomValueInDays : 185 managedGroupTypesEnum : 0 managedGroupTypes : 0 adminNotificationEmails : przemyslaw.klys@evotec.pl groupIdsToMonitorExpirations : {} policyIdentifier : 6f843b54-8fa0-4837-a8e7-b01d00d25892 #> [Array] $Groups = foreach ($ID in $Output.groupIdsToMonitorExpirations) { $Group = Get-O365Group -Id $ID if ($Group.id) { $Group.DisplayName } } [PSCustomObject] @{ GroupLifeTime = $GroupLifeTime AdminNotificationEmails = $Output.adminNotificationEmails ExpirationEnabled = $ExpirationEnabled ExpirationGroups = $Groups } } } } function Get-O365AzureGroupGeneral { <# .SYNOPSIS Get settings for Azure Groups General Tab .DESCRIPTION Get settings for Azure Groups General Tab .PARAMETER Headers Authorization header as created by Connect-O365Admin. If not provided the function will try to fetch it from the current execution context. .EXAMPLE Get-O365AzureGroupGeneral -Verbose .NOTES https://portal.azure.com/#blade/Microsoft_AAD_IAM/GroupsManagementMenuBlade/General #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $SGGM = Get-O365AzureGroupSelfService -Headers $Headers if ($SGGM) { $OutputInformation = [ordered] @{} # weird thing is that changing this userDelegationEnabled which is not available on SGGM changes selfServiceGroupManagementEnabled $OutputInformation['OwnersCanManageGroupMembershipRequests'] = $SGGM.selfServiceGroupManagementEnabled $OutputInformation['SelfServiceRestrictUserAbilityAccessGroups'] = -not $SGGM.groupsInAccessPanelEnabled $OutputInformation['AllowedToCreateSecurityGroups'] = (Get-O365AzureGroupSecurity -Headers $Headers).AllowedToCreateSecurityGroups $OutputInformation['AllowedToCreateM365Groups'] = (Get-O365AzureGroupM365 -Headers $Headers).EnableGroupCreation [PSCustomObject] $OutputInformation } } function Get-O365AzureGroupM365 { <# .SYNOPSIS Get settings for Microsoft 365 Groups - "Users can create Microsoft 365 groups in Azure portals, API or PowerShell" .DESCRIPTION Get settings for Microsoft 365 Groups - "Users can create Microsoft 365 groups in Azure portals, API or PowerShell" .PARAMETER Headers Authorization header as created by Connect-O365Admin. If not provided the function will try to fetch it from the current execution context. .PARAMETER NoTranslation Provides output without any translation. Mostly required for testing or during internal configuration. .EXAMPLE Get-O365AzureGroupM365 -Verbose .NOTES https://portal.azure.com/#blade/Microsoft_AAD_IAM/GroupsManagementMenuBlade/General #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [switch] $NoTranslation ) $Uri = 'https://graph.microsoft.com/beta/settings' $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method Get if ($Output) { if ($NoTranslation) { $Output | Where-Object { $_.DisplayName -eq "Group.Unified" } } else { $Values = ($Output | Where-Object { $_.DisplayName -eq "Group.Unified" }).values $OutputInformation = [ordered] @{} if ($Values.Count -gt 1) { foreach ($Value in $Values) { $OutputInformation[$Value.name] = if ($Value.value -eq "true") { $true } elseif ( $Value.value -eq "false") { $false } else { $Value.value } } } [PSCustomObject] $OutputInformation } } } function Get-O365AzureGroupNamingPolicy { <# .SYNOPSIS Gets the Azure Group naming policy. .DESCRIPTION Gets the Azure Group naming policy. .PARAMETER Headers Authorization header as created by Connect-O365Admin. If not provided the function will try to fetch it from the current execution context. .PARAMETER NoTranslation Provides output without any translation. Mostly required for testing or during internal configuration. .EXAMPLE Get-O365AzureGroupNamingPolicy .NOTES https://portal.azure.com/#blade/Microsoft_AAD_IAM/GroupsManagementMenuBlade/NamingPolicy #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [switch] $NoTranslation ) $Uri = 'https://graph.microsoft.com/beta/settings' $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method Get if ($Output) { if ($NoTranslation) { $Output | Where-Object { $_.DisplayName -eq "Group.Unified" } } else { $Values = ($Output | Where-Object { $_.DisplayName -eq "Group.Unified" }).values if ($Values.Count -gt 1) { $Prefix = $Values | Where-Object { $_.Name -eq 'PrefixSuffixNamingRequirement' } if ($Prefix.value) { $PrefixSplit = $Prefix.value.split('[GroupName]') [PSCUstomObject] @{ Prefix = $PrefixSplit[0] Suffix = $PrefixSplit[1] PrefixSuffixFull = $Prefix.value } } } } } } function Get-O365AzureGroupSecurity { <# .SYNOPSIS Get settings for Security Groups - "Users can create security groups in Azure portals, API or PowerShell" .DESCRIPTION Get settings for Security Groups - "Users can create security groups in Azure portals, API or PowerShell" .PARAMETER Headers Authorization header as created by Connect-O365Admin. If not provided the function will try to fetch it from the current execution context. .PARAMETER NoTranslation Provides output without any translation. Mostly required for testing or during internal configuration. .EXAMPLE Get-O365AzureGroupSecurity -Verbose .NOTES https://portal.azure.com/#blade/Microsoft_AAD_IAM/GroupsManagementMenuBlade/General #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [switch] $NoTranslation ) $Uri = 'https://graph.microsoft.com/beta/policies/authorizationPolicy/authorizationPolicy' $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method Get if ($Output) { if ($NoTranslation) { $Output } else { [PSCustomObject] @{ "AllowedToCreateSecurityGroups" = $Output.defaultUserRolePermissions.allowedToCreateSecurityGroups } } } } function Get-O365AzureGroupSelfService { <# .SYNOPSIS Gets Azure Groups Self Service information. .DESCRIPTION Gets Azure Groups Self Service information. .PARAMETER Headers Authorization header as created by Connect-O365Admin. If not provided the function will try to fetch it from the current execution context. .EXAMPLE Get-O365AzureGroupSelfService .NOTES General notes #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = 'https://main.iam.ad.ext.azure.com/api/Directories/SsgmProperties/' $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method Get if ($Output) { $Output } } function Get-O365AzureLicenses { <# .SYNOPSIS Retrieves Azure licensing information based on provided parameters. .DESCRIPTION This function retrieves Azure licensing information based on the provided parameters such as LicenseName, LicenseSKUID, ServicePlans, and ServicePlansComplete. .PARAMETER Headers Authorization header as created by Connect-O365Admin. If not provided the function will try to fetch it from the current execution context. .PARAMETER LicenseName Specifies the name of the license to retrieve information for. .PARAMETER ServicePlans Switch parameter to indicate whether to retrieve detailed service plans information. .PARAMETER ServicePlansComplete Switch parameter to indicate whether to retrieve complete service plans information. .PARAMETER LicenseSKUID Specifies the SKU ID of the license to retrieve information for. .PARAMETER IncludeLicenseDetails Switch parameter to include detailed license information along with service plans. .EXAMPLE $Licenses = Get-O365AzureLicenses $Licenses | Format-Table .EXAMPLE $ServicePlans = Get-O365AzureLicenses -ServicePlans -LicenseName 'Enterprise Mobility + Security E5' -Verbose $ServicePlans | Format-Table .EXAMPLE $ServicePlans = Get-O365AzureLicenses -ServicePlans -LicenseSKUID 'EMSPREMIUM' -Verbose $ServicePlans | Format-Table .EXAMPLE $ServicePlans = Get-O365AzureLicenses -ServicePlans -LicenseSKUID 'evotecpoland:EMSPREMIUM' -Verbose $ServicePlans | Format-Table .EXAMPLE $ServicePlans = Get-O365AzureLicenses -ServicePlans -LicenseSKUID 'evotecpoland:EMSPREMIUM' -IncludeLicenseDetails -Verbose $ServicePlans | Format-Table .NOTES Detailed information about the Get-O365AzureLicenses function and its usage scenarios. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [string] $LicenseName, [switch] $ServicePlans, [switch] $ServicePlansComplete, [string] $LicenseSKUID, [switch] $IncludeLicenseDetails ) # Maybe change it to https://docs.microsoft.com/en-us/graph/api/subscribedsku-list?view=graph-rest-1.0&tabs=http # Or maybe not because it doesn't contain exactly same data missing displayName from service plans # $Uri = "https://graph.microsoft.com/v1.0/subscribedSkus" $Uri = "https://main.iam.ad.ext.azure.com/api/AccountSkus" $QueryParameter = @{ backfillTenants = $false } if (-not $Script:AzureLicensesList) { Write-Verbose -Message "Get-O365AzureLicenses - Querying for Licenses SKU" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -QueryParameter $QueryParameter # We build a list of all the licenses, for caching purposes if ($Output) { $Script:AzureLicensesList = $Output } } else { Write-Verbose -Message "Get-O365AzureLicenses - Reusing cache for Licenses SKU" $Output = $Script:AzureLicensesList } # If license name or license id is provided we filter thjings out if ($LicenseName) { $Output = $Output | Where-Object { $_.Name -eq $LicenseName } } elseif ($LicenseSKUID) { $Output = $Output | Where-Object { $TempSplit = $_.AccountSkuId -split ':' $TempSplit[1] -eq $LicenseSKUID -or $_.AccountSkuId -eq $LicenseSKUID } } # we then based on ServicePlans request only display service plans if ($ServicePlans) { foreach ($O in $Output) { if ($IncludeLicenseDetails) { foreach ($Plan in $O.serviceStatuses.servicePlan) { [PSCustomObject] @{ LicenseName = $O.Name LicenseSKUID = $O.AccountSkuId ServiceDisplayName = $Plan.displayName ServiceName = $Plan.serviceName ServicePlanId = $Plan.servicePlanId ServiceType = $Plan.serviceType } } } else { $O.serviceStatuses.servicePlan } } } elseif ($ServicePlansComplete) { # or display everything foreach ($O in $Output) { [PSCustomObject] @{ Name = $O.Name AccountSkuID = $O.AccountSkuId ServicePlan = $O.serviceStatuses.servicePlan AvailableUnits = $o.availableUnits TotalUnits = $O.totalUnits ConsumedUnits = $O.consumedUnits WarningUnits = $O.warningUnits } } } else { $Output } } # https://main.iam.ad.ext.azure.com/api/AccountSkus/UserAssignments?accountSkuID=evotecpoland%3AEMSPREMIUM&nextLink=&searchText=&columnName=&sortOrder=undefined # https://main.iam.ad.ext.azure.com/api/AccountSkus/UserAssignments?accountSkuID=evotecpoland%3AEMSPREMIUM&nextLink=&searchText=&columnName=&sortOrder=undefined # https://main.iam.ad.ext.azure.com/api/AccountSkus/GroupAssignments?accountSkuID=evotecpoland%3AEMSPREMIUM&nextLink=&searchText=&sortOrder=undefined function Get-O365AzureMultiFactorAuthentication { <# .SYNOPSIS Retrieves the Multi-Factor Authentication settings for the specified tenant. .DESCRIPTION This function retrieves the Multi-Factor Authentication settings for the specified tenant using the provided headers. .PARAMETER Headers Authorization header as created by Connect-O365Admin. If not provided the function will try to fetch it from the current execution context. .EXAMPLE Get-O365AzureMultiFactorAuthentication -Verbose An example of how to retrieve Multi-Factor Authentication settings for a tenant. .NOTES Based on: https://portal.azure.com/#blade/Microsoft_AAD_IAM/MultifactorAuthenticationMenuBlade/GettingStarted/fromProviders/ #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) #$Uri = "https://main.iam.ad.ext.azure.com/api/MultiFactorAuthentication/GetOrCreateExpandedTenantModel?tenantName=Evotec" $Uri = "https://main.iam.ad.ext.azure.com/api/MultiFactorAuthentication/GetOrCreateExpandedTenantModel" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers $Output } function Get-O365AzureProperties { <# .SYNOPSIS Reads the properties of Azure Active Directory (Azure AD) for the current tenant. .DESCRIPTION Reads the properties of Azure Active Directory (Azure AD) for the current tenant. .PARAMETER Headers Authorization header as created by Connect-O365Admin. If not provided the function will try to fetch it from the current execution context. .PARAMETER NoTranslation Return information as provided by API, rather than translated to only values visible in GUI .EXAMPLE Get-O365AzureProperties -Verbose .NOTES General notes #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [switch] $NoTranslation ) $Uri = 'https://main.iam.ad.ext.azure.com/api/Directory' $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers if ($Output) { if ($NoTranslation) { $Output } else { [PSCustomObject] @{ DisplayName = $Output.DisplayName NotificationLanguage = $Output.preferredLanguage TechnicalContact = if ($Output.technicalNotificationMails.Count -gt 0) { $Output.technicalNotificationMails[0] } else { '' } GlobalPrivacyContact = $Output.privacyProfile.contactEmail PrivacyStatementURL = $Output.privacyProfile.statementUrl } } } } function Get-O365AzurePropertiesSecurity { <# .SYNOPSIS Retrieves the security default status for the Office 365 tenant. .DESCRIPTION This function retrieves the security default status for the Office 365 tenant using the provided headers. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .EXAMPLE Get-O365AzurePropertiesSecurity -Headers $headers An example of how to retrieve the security default status for the Office 365 tenant using specified headers. .NOTES This function is designed to work with the Office 365 API to fetch the security default status for the tenant. It requires a valid set of headers, including authorization tokens, to authenticate the request. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = 'https://main.iam.ad.ext.azure.com/api/SecurityDefaults/GetSecurityDefaultStatus' $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers if ($Output) { $Output } } function Get-O365AzureTenantSKU { <# .SYNOPSIS Retrieves the SKU information for the Office 365 tenant. .DESCRIPTION This function retrieves the SKU information for the Office 365 tenant using the provided headers. The SKU information includes details about the tenant's subscription and licensing. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .EXAMPLE Get-O365AzureTenantSKU -Headers $headers An example of how to retrieve the SKU information for the Office 365 tenant using specified headers. .NOTES This function is designed to work with the Office 365 API to fetch the SKU information for the tenant. It requires a valid set of headers, including authorization tokens, to authenticate the request. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = 'https://main.iam.ad.ext.azure.com/api/TenantSkuInfo' $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers if ($Output) { $Output } } function Get-O365AzureUserSettings { <# .SYNOPSIS Retrieves Azure user settings from the specified URI. .DESCRIPTION This function retrieves Azure user settings from the specified URI using the provided headers. .PARAMETER Headers Specifies the headers required for the API request. .EXAMPLE Get-O365AzureUserSettings -Headers $Headers An example of how to retrieve Azure user settings using specified headers. .NOTES Based on: https://main.iam.ad.ext.azure.com/api/Directories/Properties #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [switch] $NoTranslation ) $Uri = "https://main.iam.ad.ext.azure.com/api/Directories/Properties" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method GET if ($Output) { if ($NoTranslation) { $Output } else { [PSCustomObject] @{ objectId = $Output.objectId #: ceb371f6 - 8745 - 4876-a040 - 69f2d10a9d1a displayName = $Output.displayName #: Evotec usersCanRegisterApps = $Output.usersCanRegisterApps #: True isAnyAccessPanelPreviewFeaturesAvailable = $Output.isAnyAccessPanelPreviewFeaturesAvailable #: False showMyGroupsFeature = $Output.showMyGroupsFeature #: False myGroupsFeatureValue = $Output.myGroupsFeatureValue #: myGroupsGroupId = $Output.myGroupsGroupId #: myGroupsGroupName = $Output.myGroupsGroupName #: showMyAppsFeature = $Output.showMyAppsFeature #: False myAppsFeatureValue = $Output.myAppsFeatureValue #: myAppsGroupId = $Output.myAppsGroupId #: myAppsGroupName = $Output.myAppsGroupName #: showUserActivityReportsFeature = $Output.showUserActivityReportsFeature #: False userActivityReportsFeatureValue = $Output.userActivityReportsFeatureValue #: userActivityReportsGroupId = $Output.userActivityReportsGroupId #: userActivityReportsGroupName = $Output.userActivityReportsGroupName #: showRegisteredAuthMethodFeature = $Output.showRegisteredAuthMethodFeature #: False registeredAuthMethodFeatureValue = $Output.registeredAuthMethodFeatureValue #: registeredAuthMethodGroupId = $Output.registeredAuthMethodGroupId #: registeredAuthMethodGroupName = $Output.registeredAuthMethodGroupName #: usersCanAddExternalUsers = $Output.usersCanAddExternalUsers #: False limitedAccessCanAddExternalUsers = $Output.limitedAccessCanAddExternalUsers #: False restrictDirectoryAccess = $Output.restrictDirectoryAccess #: False groupsInAccessPanelEnabled = $Output.groupsInAccessPanelEnabled #: False selfServiceGroupManagementEnabled = $Output.selfServiceGroupManagementEnabled #: True securityGroupsEnabled = $Output.securityGroupsEnabled #: False usersCanManageSecurityGroups = $Output.usersCanManageSecurityGroups #: office365GroupsEnabled = $Output.office365GroupsEnabled #: False usersCanManageOfficeGroups = $Output.usersCanManageOfficeGroups #: allUsersGroupEnabled = $Output.allUsersGroupEnabled #: False scopingGroupIdForManagingSecurityGroups = $Output.scopingGroupIdForManagingSecurityGroups #: scopingGroupIdForManagingOfficeGroups = $Output.scopingGroupIdForManagingOfficeGroups #: scopingGroupNameForManagingSecurityGroups = $Output.scopingGroupNameForManagingSecurityGroups #: scopingGroupNameForManagingOfficeGroups = $Output.scopingGroupNameForManagingOfficeGroups #: objectIdForAllUserGroup = $Output.objectIdForAllUserGroup #: allowInvitations = $Output.allowInvitations #: False isB2CTenant = $Output.isB2CTenant #: False restrictNonAdminUsers = $Output.restrictNonAdminUsers #: False toEnableLinkedInUsers = $Output.toEnableLinkedInUsers #: {} toDisableLinkedInUsers = $Output.toDisableLinkedInUsers #: {} # We try to make it the same as shown in Set-O365UserSettings linkedInAccountConnection = if ($Output.enableLinkedInAppFamily -eq 4) { $true } elseif ($Output.enableLinkedInAppFamily -eq 0) { $true } else { $false } linkedInSelectedGroupObjectId = $Output.linkedInSelectedGroupObjectId #: b6cdb9c3-d660 - 4558-bcfd - 82c14a986b56 linkedInSelectedGroupDisplayName = $Output.linkedInSelectedGroupDisplayName #: All Users } } } } function Get-O365BillingAccounts { <# .SYNOPSIS Retrieves billing accounts information from Office 365. .DESCRIPTION This function retrieves billing accounts information from Office 365 using the provided headers. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .EXAMPLE Get-O365BillingAccounts -Headers $headers #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://admin.microsoft.com/fd/jarvisCM/my-org/profiles?type=organization" $Uri = "https://admin.microsoft.com/fd/commerceMgmt/billingaccount" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers $Output } function Get-O365BillingInvoices { <# .SYNOPSIS Gets all invoices from Office 365. If no StartDate and EndDate are specified last 6 months are used. .DESCRIPTION Gets all invoices from Office 365. If no StartDate and EndDate are specified last 6 months are used. .PARAMETER Headers Parameter description .PARAMETER StartDate Provide StartDate for the invoices to be retrieved. If not specified, StartDate is set to 6 months ago. .PARAMETER EndDate Provide EndDate for the invoices to be retrieved. If not specified, EndDate is set to current date. .EXAMPLE Get-O365BillingInvoices -Headers $headers -StartDate (Get-Date).AddMonths(-6) -EndDate (Get-Date) .NOTES This function retrieves invoices from Office 365. If no specific StartDate and EndDate are provided, the function defaults to retrieving invoices from the last 6 months. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [DateTime] $StartDate, [DateTime] $EndDate ) if (-not $StartDate) { $StartDate = (Get-Date).AddMonths(-6) } if (-not $EndDate) { $EndDate = Get-Date } $StartDateText = $StartDate.ToString("yyyy-MM-dd") $EndDateText = $EndDate.ToString("yyyy-MM-dd") $Uri = "https://admin.microsoft.com/fd/commerceapi/my-org/legacyInvoices(startDate=$StartDateText,endDate=$EndDateText)" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers $Output } <# Not sure where I got this from function Get-O365BillingLicenseAutoClaim { [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) if ($Headers) { $TentantID = $Headers.Tenant } else { $TentantID = $Script:AuthorizationO365Cache.Tenant } $Uri = "https://admin.microsoft.com/fd/m365licensing/v1/tenants/$TentantID/licenseddevicesassets" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers $Output.items } #> function Get-O365BillingLicenseAutoClaim { <# .SYNOPSIS Retrieves information about licensed devices assets for a specific Office 365 tenant. .DESCRIPTION This function retrieves information about licensed devices assets for a specific Office 365 tenant using the provided headers. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .EXAMPLE Get-O365BillingLicenseAutoClaim -Headers $headers #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://admin.microsoft.com/fd/m365licensing/v1/policies/autoclaim" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers $Output } function Get-O365BillingLicenseRequests { <# .SYNOPSIS Retrieves self-service license requests for a specific Office 365 tenant. .DESCRIPTION This function retrieves self-service license requests for a specific Office 365 tenant using the provided headers. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .EXAMPLE Get-O365BillingLicenseRequests -Headers $headers #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) if ($Headers) { $TentantID = $Headers.Tenant } else { $TentantID = $Script:AuthorizationO365Cache.Tenant } $Uri = "https://admin.microsoft.com/fd/m365licensing/v1/tenants/$TentantID/self-service-requests" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers $Output.items } function Get-O365BillingNotifications { <# .SYNOPSIS Retrieves invoice preference settings for billing notifications in Office 365. .DESCRIPTION This function retrieves invoice preference settings for billing notifications in Office 365 from the specified API endpoint using the provided headers. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .EXAMPLE Get-O365BillingNotifications -Headers $headers #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://admin.microsoft.com/fd/commerceMgmt/mgmtsettings/invoicePreference?api-version=1.0 " $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers $Output } function Get-O365BillingNotificationsList { <# .SYNOPSIS Retrieves a list of billing notification users in Office 365. .DESCRIPTION This function retrieves a list of billing notification users in Office 365 from the specified API endpoint using the provided headers. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .EXAMPLE Get-O365BillingNotificationsList -Headers $headers #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://admin.microsoft.com/fd/commerceMgmt/mgmtsettings/billingNotificationUsers?api-version=1.0" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers $Output } <# Not working function Get-O365BillingNotificationsList { [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://admin.microsoft.com/admin/api/Users/ListBillingNotificationsUsers" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST $Output } Get-O365BillingNotificationsList #> function Get-O365BillingPaymentMethods { <# .SYNOPSIS Retrieves unsettled charges for payment instruments in the specified organization. .DESCRIPTION This function retrieves unsettled charges for payment instruments in the organization from the specified API endpoint using the provided headers. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .EXAMPLE Get-O365BillingPaymentMethods -Headers $headers #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [string] $ID ) if ($ID) { # $Uri = "https://admin.microsoft.com/fd/commerceapi/my-org/paymentInstruments($ID)/unsettledCharges" $Uri = "https://admin.microsoft.com/fd/commerceapi/my-org/paymentInstruments($ID)" } else { $Uri = "https://admin.microsoft.com/fd/commerceapi/my-org/paymentInstruments" } $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers $Output } function Get-O365BillingProfile { <# .SYNOPSIS Retrieves billing profile information for a specific billing group in Office 365. .DESCRIPTION This function retrieves billing profile information for a specified billing group in Office 365 from the designated API endpoint using the provided headers. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .EXAMPLE Get-O365BillingProfile -Headers $headers #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) # But how do I get AccountID ? $AccountID = '' $Uri = "https://admin.microsoft.com/fd/commerceMgmt/moderncommerce/myroles/BillingGroup?api-version=3.0&accountId=$AccountID" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method GET -Body $Body $Output } function Get-O365BillingSubscriptions { <# .SYNOPSIS Retrieves billing subscriptions for a specific organization in Office 365. .DESCRIPTION This function retrieves billing subscriptions for a specified organization in Office 365 from the designated API endpoint using the provided headers. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .PARAMETER Property An array of properties to include in the query response. .PARAMETER OrderBy The property to order the query results by. .EXAMPLE Get-O365BillingSubscriptions -Headers $headers -Property @('displayName', 'status') -OrderBy 'displayName' #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [string[]]$Property, [string] $OrderBy ) #$Uri = "https://admin.microsoft.com/fd/commerceapi/my-org/subscriptions?`$filter=parentId%20eq%20null&`$expand=subscribedsku&optional=cspsubscriptions,price,actions,transitiondetails,quickstarttag" $Uri = "https://admin.microsoft.com/fd/commerceapi/my-org/subscriptions" $QueryParameter = @{ '$Select' = $Property -join ',' '$filter' = 'parentId eq null' '$orderby' = $OrderBy 'expand' = 'subscribedsku' 'optional' = "cspsubscriptions,price,actions,transitiondetails,quickstarttag" } Remove-EmptyValue -Hashtable $QueryParameter $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -QueryParameter $QueryParameter $Output } function Get-O365ConsiergeAll { <# .SYNOPSIS Retrieves configuration information for the Concierge service in Office 365. .DESCRIPTION This function retrieves configuration information for the Concierge service in Office 365 from the specified API endpoint using the provided headers. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .EXAMPLE Get-O365ConsiergeAll -Headers $headers #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://admin.microsoft.com/api/concierge/GetConciergeConfigAll" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers $Output } function Get-O365CopilotPin { [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://admin.microsoft.com/admin/api/settings/company/copilotpolicy/pin" $OutputSettings = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method GET $OutputSettings } function Get-O365DirectorySync { <# .SYNOPSIS Retrieves directory synchronization settings from Office 365. .DESCRIPTION This function retrieves directory synchronization settings from Office 365 using the specified API endpoint and headers. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://admin.microsoft.com/admin/api/settings/apps/dirsync" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers $Output } function Get-O365DirectorySyncErrors { <# .SYNOPSIS Retrieves directory synchronization errors from Office 365. .DESCRIPTION This function retrieves directory synchronization errors from Office 365 using the specified API endpoint and headers. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .EXAMPLE Get-O365DirectorySyncErrors -Headers $headers #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://admin.microsoft.com/admin/api/dirsyncerrors/listdirsyncerrors" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST if ($Output.ObjectsWithErrorsList) { $Output.ObjectsWithErrorsList } } function Get-O365DirectorySyncManagement { <# .SYNOPSIS Retrieves directory synchronization management details from Office 365. .DESCRIPTION This function retrieves directory synchronization management details from Office 365 using the specified API endpoint and headers. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://admin.microsoft.com/admin/api/DirsyncManagement/manage" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers $Output } function Get-O365Domain { <# .SYNOPSIS Retrieves domain information from Office 365. .DESCRIPTION This function retrieves domain information from Office 365 using the specified API endpoint and headers. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .EXAMPLE Get-O365Domain -Headers $headers #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) #$Uri = "https://admin.microsoft.com/admin/api/Domains/List?filter=&searchText=&computeDomainRegistrationData=true" $Uri = "https://admin.microsoft.com/admin/api/Domains/List" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers $Output } function Get-O365DomainDependencies { <# .SYNOPSIS Provides functionality to retrieve domain dependencies in Office 365. .DESCRIPTION This function allows you to query and retrieve dependencies related to a specific domain in Office 365 using the provided headers. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .PARAMETER DomainName The name of the domain for which to retrieve dependencies. .PARAMETER Type Specifies the type of dependencies to retrieve. Valid values are 'All', 'Users', 'TeamsAndGroups', and 'Apps'. Default is 'All'. .EXAMPLE Get-O365DomainDependencies -Headers $headers -DomainName 'example.com' -Type 'Users' #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [parameter(Mandatory)][string] $DomainName, [string][ValidateSet('All', 'Users', 'TeamsAndGroups', 'Apps')] $Type = 'All' ) $Uri = "https://admin.microsoft.com/admin/api/Domains/Dependencies" $Types = @{ 'All' = 0 'Users' = 1 'Groups' = 2 'Apps' = 4 } $QueryParameter = @{ 'domainName' = $DomainName 'kind' = $Types[$Type] } $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -QueryParameter $QueryParameter -Method POST if ($Output.Succeeded) { $Output.Data.Dependencies } else { [PSCustomObject] @{ DomainName = $DomainName Status = $false Message = $Output.Message } } } function Get-O365DomainHealth { <# .SYNOPSIS Provides functionality to check the DNS health of a specified domain in Office 365. .DESCRIPTION This function allows you to query and check the DNS health of a specific domain in Office 365 using the provided headers. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .PARAMETER DomainName The name of the domain for which to check DNS health. .EXAMPLE Get-O365DomainHealth -Headers $headers -DomainName 'example.com' #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [parameter(Mandatory)][string] $DomainName ) $Uri = "https://admin.microsoft.com/admin/api/Domains/CheckDnsHealth" $QueryParameter = @{ 'domainName' = $DomainName 'overrideSkip' = $true 'canRefreshCache' = $true 'dnsHealthCheckScenario' = 2 } $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -QueryParameter $QueryParameter if ($Output.Succeeded) { $Output.Data } else { $Output } } <# function Get-O365DomainRegistrarsInformation { [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers #, # [parameter(Mandatory)][string] $DomainName ) $Uri = "https://admin.microsoft.com/admin/api/Domains/GetRegistrarsHelpInfo" $QueryParameter = @{ #'domainName' = $DomainName #'overrideSkip' = $true #'canRefreshCache' = $true #'dnsHealthCheckScenario' = 2 } $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -QueryParameter $QueryParameter $Output } #> function Get-O365DomainRecords { <# .SYNOPSIS Provides functionality to retrieve domain records for a specified domain in Office 365. .DESCRIPTION This function allows you to query and retrieve domain records for a specific domain in Office 365 using the provided headers. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .PARAMETER DomainName The name of the domain for which to retrieve records. .EXAMPLE Get-O365DomainRecords -Headers $headers -DomainName 'example.com' #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [parameter(Mandatory)][string] $DomainName ) $Uri = "https://admin.microsoft.com/admin/api/Domains/Records" $QueryParameter = @{ 'domainName' = $DomainName } $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -QueryParameter $QueryParameter $Output } function Get-O365DomainTroubleshooting { <# .SYNOPSIS Provides troubleshooting information for a specified domain in Office 365. .DESCRIPTION This function allows you to check if troubleshooting is allowed for a specific domain in Office 365 using the provided headers. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .PARAMETER DomainName The name of the domain to check troubleshooting for. .EXAMPLE Get-O365DomainTroubleshooting -Headers $headers -DomainName 'example.com' #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [parameter(Mandatory)][string] $DomainName ) $Uri = "https://admin.microsoft.com/admin/api/Domains/CheckIsTroubleshootingAllowed" $QueryParameter = @{ 'domainName' = $DomainName #'overrideSkip' = $true 'canRefreshCache' = $true #'dnsHealthCheckScenario' = 2 } $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -QueryParameter $QueryParameter $Output } function Get-O365Group { <# .SYNOPSIS Provides functionality to retrieve Office 365 group information based on various parameters. .DESCRIPTION This function allows you to query and retrieve group information from Office 365 based on different criteria such as ID, display name, email address, and more. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .PARAMETER Id The ID of the group to query. .PARAMETER DisplayName The display name of the group to query. .PARAMETER EmailAddress The email address of the group to query. .PARAMETER Property An array of properties to include in the query response. .PARAMETER Filter The filter to apply to the query. .PARAMETER OrderBy The property to order the query results by. .EXAMPLE Get-O365Group -Headers $headers -DisplayName 'MyGroup' -Property @('displayName', 'mail') #> [cmdletBinding(DefaultParameterSetName = 'Default')] param( [parameter(ParameterSetName = 'UnifiedGroupsOnly')] [parameter(ParameterSetName = 'Default')] [parameter(ParameterSetName = 'Filter')] [parameter(ParameterSetName = 'EmailAddress')] [parameter(ParameterSetName = 'DisplayName')] [parameter(ParameterSetName = 'Id')] [alias('Authorization')][System.Collections.IDictionary] $Headers, [parameter(ParameterSetName = 'Id')][string] $Id, [parameter(ParameterSetName = 'DisplayName')][string] $DisplayName, [alias('Mail')][parameter(ParameterSetName = 'EmailAddress')][string] $EmailAddress, [parameter(ParameterSetName = 'UnifiedGroupsOnly')] [parameter(ParameterSetName = 'Default')] [parameter(ParameterSetName = 'Filter')] [parameter(ParameterSetName = 'EmailAddress')] [parameter(ParameterSetName = 'DisplayName')] [parameter(ParameterSetName = 'Id')] [string[]] $Property, [parameter(ParameterSetName = 'Default')] [parameter(ParameterSetName = 'Filter')][string] $Filter, [parameter(ParameterSetName = 'UnifiedGroupsOnly')] [parameter(ParameterSetName = 'Default')] [parameter(ParameterSetName = 'Filter')] [string] $OrderBy, [parameter(ParameterSetName = 'UnifiedGroupsOnly')] [switch] $UnifiedGroupsOnly ) if ($DisplayName) { $Uri = 'https://graph.microsoft.com/v1.0/groups' $QueryParameter = @{ '$Select' = $Property -join ',' '$filter' = "displayName eq '$DisplayName'" } } elseif ($EmailAddress) { $Uri = 'https://graph.microsoft.com/v1.0/groups' $QueryParameter = @{ '$Select' = $Property -join ',' '$filter' = "mail eq '$EmailAddress'" } } elseif ($ID) { # Query a single group $Uri = "https://graph.microsoft.com/v1.0/groups/$ID" $QueryParameter = @{ '$Select' = $Property -join ',' } } elseif ($UnifiedGroupsOnly) { $Uri = "https://graph.microsoft.com/v1.0/groups" $QueryParameter = @{ '$Select' = $Property -join ',' '$filter' = "groupTypes/any(c: c eq 'Unified')" '$orderby' = $OrderBy } } else { # Query multiple groups $Uri = 'https://graph.microsoft.com/v1.0/groups' $QueryParameter = @{ '$Select' = $Property -join ',' '$filter' = $Filter '$orderby' = $OrderBy } } Remove-EmptyValue -Hashtable $QueryParameter Invoke-O365Admin -Uri $Uri -Headers $Headers -QueryParameter $QueryParameter } function Get-O365GroupAdministrativeUnit { <# .SYNOPSIS Retrieves the administrative unit of an Office 365 group. .DESCRIPTION This function retrieves the administrative unit of an Office 365 group based on the provided GroupID or GroupDisplayName. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .PARAMETER GroupID The ID of the group to query. Default value is '75233998-a950-41de-97d0-6c259d0580a7'. .PARAMETER GroupDisplayName The display name of the group to query. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [parameter()][string] $GroupID = '75233998-a950-41de-97d0-6c259d0580a7' ) if ($GroupID) { $Group = $GroupID } elseif ($GroupDisplayName) { $Group = $GroupDisplayName } #$Uri = "https://graph.microsoft.com/beta/groups/$Group/memberOf/microsoft.graph.administrativeUnit" $Uri = "https://graph.microsoft.com/v1.0/groups/$Group/memberOf/microsoft.graph.administrativeUnit" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers $Output } function Get-O365GroupLicenses { <# .SYNOPSIS Retrieves the licenses information for a specified Office 365 group. .DESCRIPTION This function retrieves the licenses information for an Office 365 group based on the provided GroupID or GroupDisplayName. It can also include detailed service plans information if specified. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .PARAMETER GroupID The ID of the group to query. .PARAMETER GroupDisplayName The display name of the group to query. .PARAMETER ServicePlans Switch parameter to indicate whether to retrieve detailed service plans information. .PARAMETER NoTranslation Switch parameter to skip translation of the output. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [parameter()][string] $GroupID, [parameter()][alias('GroupName')][string] $GroupDisplayName, [switch] $ServicePlans, [switch] $NoTranslation ) if ($GroupID) { $Group = $GroupID } elseif ($GroupDisplayName) { $GroupSearch = Get-O365Group -DisplayName $GroupDisplayName if ($GroupSearch.id) { $Group = $GroupSearch.id } } if ($Group) { $Uri = "https://main.iam.ad.ext.azure.com/api/AccountSkus/Group/$Group" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers if ($Output) { if ($NoTranslation) { $Output } else { foreach ($License in $Output.licenses) { $SP = Convert-SKUToLicense -SKU $License.accountSkuID if ($SP) { $ServicePlansPrepared = Find-EnabledServicePlan -ServicePlans $SP -DisabledServicePlans $License.disabledServicePlans [PSCustomObject] @{ License = $SP[0].LicenseName LicenseSKUID = $SP[0].LicenseSKUID Enabled = $ServicePlansPrepared.Enabled.ServiceDisplayName Disabled = $ServicePlansPrepared.Disabled.ServiceDisplayName EnabledPlan = $ServicePlansPrepared.Enabled DisabledPlan = $ServicePlansPrepared.Disabled } } } } } } } function Get-O365GroupMember { <# .SYNOPSIS Retrieves members of an Office 365 group based on the provided group ID. .DESCRIPTION This function queries the Microsoft Graph API to retrieve members of an Office 365 group using the specified group ID. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .PARAMETER Id The ID of the Office 365 group for which members are to be retrieved. .PARAMETER Search A search query to filter the members of the group. .PARAMETER Property An array of properties to include in the query results. .EXAMPLE Get-O365GroupMember -Headers $headers -Id 'groupID' -Search 'searchQuery' -Property @('property1', 'property2') #> [cmdletBinding()] param( [parameter()][alias('Authorization')][System.Collections.IDictionary] $Headers, [parameter(Mandatory)][string] $Id, [string] $Search, [string[]] $Property ) if ($ID) { # Query a single group $Uri = "https://graph.microsoft.com/v1.0/groups/$ID/members" $QueryParameter = @{ '$Select' = $Property -join ',' '$Search' = $Search } if ($QueryParameter.'$Search') { # This is required for search to work # https://developer.microsoft.com/en-us/identity/blogs/build-advanced-queries-with-count-filter-search-and-orderby/ $Headers['ConsistencyLevel'] = 'eventual' } Remove-EmptyValue -Hashtable $QueryParameter Invoke-O365Admin -Uri $Uri -Headers $Headers -QueryParameter $QueryParameter } } function Get-O365OrgAccountLinking { <# .SYNOPSIS Users who connect their Azure AD account with their MSA account can earn rewards points when they search on Bing. User searches are never shared. .DESCRIPTION Users who connect their Azure AD account with their MSA account can earn rewards points when they search on Bing. User searches are never shared. .PARAMETER Headers The headers to use for the request .EXAMPLE Get-O365OrgAccountLinking .NOTES General notes #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://admin.microsoft.com/fd/bfb/api/v3/office/switch/feature" $OutputSettings = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST if ($OutputSettings) { [PSCustomObject] @{ AccountLinking = if ($OutputSettings.result -contains 'AccountLinking') { $true } else { $false } } } } function Get-O365OrgAdoptionScore { <# .SYNOPSIS Retrieves the Organization Adoption Score for the organization. .DESCRIPTION This function queries the Microsoft Graph API to retrieve the Organization Adoption Score for the organization. The Organization Adoption Score is a feature that helps organizations measure and improve their adoption of Microsoft 365 services. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. This parameter is required to authenticate the request. .EXAMPLE Get-O365OrgAdoptionScore -Headers $headers This example retrieves the Organization Adoption Score for the organization using the provided headers for authentication. .NOTES This function requires a valid authentication token to be passed in the Headers parameter. The token should include the necessary permissions to access the Organization Adoption Score. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://admin.microsoft.com/admin/api/reports/productivityScoreCustomerOption" $OutputSettings = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method GET if ($OutputSettings) { if ($OutputSettings.Output) { try { $OutputSettings.Output | ConvertFrom-Json -ErrorAction Stop } catch { Write-Warning -Message "Get-O365OrgAdoptionScore - Unable to convert output from JSON $($_.Exception.Message)" } } } } function Get-O365OrgAdoptionScoreConfig { <# .SYNOPSIS Retrieves the Organization Adoption Score Configuration for the organization. .DESCRIPTION This function queries the Microsoft Graph API to retrieve the Organization Adoption Score Configuration for the organization. The Organization Adoption Score is a feature that helps organizations measure and improve their adoption of Microsoft 365 services. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. This parameter is required to authenticate the request. .EXAMPLE Get-O365OrgAdoptionScoreConfig -Headers $headers This example retrieves the Organization Adoption Score Configuration for the organization using the provided headers for authentication. .NOTES This function requires a valid authentication token to be passed in the Headers parameter. The token should include the necessary permissions to access the Organization Adoption Score Configuration. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://admin.microsoft.com/admin/api/reports/productivityScoreConfig/GetProductivityScoreConfig" $OutputSettings = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method GET if ($OutputSettings) { if ($OutputSettings.Output) { try { $OutputSettings.Output | ConvertFrom-Json -ErrorAction Stop } catch { Write-Warning -Message "Get-O365OrgAdoptionScore - Unable to convert output from JSON $($_.Exception.Message)" } } } } <# TenantId : CEB371F687454876A04069F2D10A9D1A ProductivityScoreSignedup : True SignupUserPuid : 10030000944DB84D SignupTime : 2021-05-22T15:03:09.6894484+00:00 ReadyTime : 2021-05-22T18:52:10.0074484+00:00 AdoptionScorePreOptedOut : False PreOptedOutUserPuid : PreOptedOutTime : 0001-01-01T00:00:00 #> <# $session = New-Object Microsoft.PowerShell.Commands.WebRequestSession $session.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.2045.31" $session.Cookies.Add((New-Object System.Net.Cookie("MC1", "GUID=ddaa99563cae4ea7886e4ec3b3b65816&HASH=ddaa&LV=202302&V=4&LU=1675709115517", "/", ".microsoft.com"))) $session.Cookies.Add((New-Object System.Net.Cookie("x-portal-routekey", "frc", "/", "admin.microsoft.com"))) $session.Cookies.Add((New-Object System.Net.Cookie("p.BDId", "1beed528-292c-46ff-984b-a0381412e186", "/", "admin.microsoft.com"))) $session.Cookies.Add((New-Object System.Net.Cookie("s.AjaxSessionKey", "RKVmBkPFeoFItafEbR6EzK1YXjonPABkGkd6MUG5qS6p5KN7kaWXxsEc8yLpECj0jKCvc%2B7N3CjJiLqTHyXP9Q%3D%3D", "/", "admin.microsoft.com"))) $session.Cookies.Add((New-Object System.Net.Cookie("s.CURedir", "True", "/", "admin.microsoft.com"))) $session.Cookies.Add((New-Object System.Net.Cookie("s.DCLoc", "frcprod", "/", "admin.microsoft.com"))) $session.Cookies.Add((New-Object System.Net.Cookie("s.MFG", "True", "/", "admin.microsoft.com"))) $session.Cookies.Add((New-Object System.Net.Cookie("p.TenantCulture", "ceb371f6-8745-4876-a040-69f2d10a9d1a::pl-PL", "/", "admin.microsoft.com"))) $session.Cookies.Add((New-Object System.Net.Cookie("s.DisplayCulture", "en-US", "/", "admin.microsoft.com"))) $session.Cookies.Add((New-Object System.Net.Cookie("s.cachemap", "21", "/", "admin.microsoft.com"))) $session.Cookies.Add((New-Object System.Net.Cookie("at_check", "true", "/", ".microsoft.com"))) $session.Cookies.Add((New-Object System.Net.Cookie("MicrosoftApplicationsTelemetryDeviceId", "e01995fb-07ec-49ee-8e9d-18523250772b", "/", "admin.microsoft.com"))) $session.Cookies.Add((New-Object System.Net.Cookie("MicrosoftApplicationsTelemetryFirstLaunchTime", "2023-02-10T08:45:14.247Z", "/", "admin.microsoft.com"))) $session.Cookies.Add((New-Object System.Net.Cookie("p.UtcOffset", "-120", "/", "admin.microsoft.com"))) $session.Cookies.Add((New-Object System.Net.Cookie("MSCC", "cid=c9n5zpp31dsappt5iwgis9uh-c1=2-c2=2-c3=2", "/", ".microsoft.com"))) $session.Cookies.Add((New-Object System.Net.Cookie("MUID", "043B5B7D7C466052000849907DC56114", "/", ".microsoft.com"))) $session.Cookies.Add((New-Object System.Net.Cookie("AMCVS_EA76ADE95776D2EC7F000101%40AdobeOrg", "1", "/", ".microsoft.com"))) $session.Cookies.Add((New-Object System.Net.Cookie("s.SessID", "d5a8d432-eb7b-4867-9fb7-fa159fc69450", "/", "admin.microsoft.com"))) $session.Cookies.Add((New-Object System.Net.Cookie("s.Cart", "{`"BaseOffers`":null,`"Frequency`":0,`"IWPurchaseUserId`":null,`"PromotionCodes`":null,`"IsOfferTransition`":false}", "/", "admin.microsoft.com"))) $session.Cookies.Add((New-Object System.Net.Cookie("s.InNewAdmin", "True", "/", "admin.microsoft.com"))) $session.Cookies.Add((New-Object System.Net.Cookie("market", "PL", "/", ".microsoft.com"))) $session.Cookies.Add((New-Object System.Net.Cookie("fptctx2", "taBcrIH61PuCVH7eNCyH0B9zcK90d%252bIeoo1r5v7Zc255mYjwcvIyy5SXEpMD5ZZmKtx8SvGsNdflRgroe1lGFQjbRB2oIOUZnp7ZuzTwF6ML4CUkA2fz%252firyPQA1EFJP9mWScg0dMyOIYsQGMIHQg6fTt0hGhZf9A6Oq0Eh4nikMmzoAB1jEIbK2HsSS81IMMhx5t0knQJrj4M6Vet4nLKXsWDSebMGDMv1AAY4GuaOT8VEffwqCWe6ZI3gEKTzUMp1XJ%252bw4SpnwewPGH3kBxgr4vzIEFqyebSD98xMv9YUmOdTLeq%252f2JgZRRUmC8L4cr%252bWPXrPD1DZVJdnlXfjYM0jRNANLnYqaWFWJCiB4q7Q%253d", "/", ".microsoft.com"))) $session.Cookies.Add((New-Object System.Net.Cookie("s.ImpressionId", "4f371552-4ad3-41b6-b115-00fa0cc7db21", "/", "admin.microsoft.com"))) $session.Cookies.Add((New-Object System.Net.Cookie("s.classic", "False", "/", "admin.microsoft.com"))) $session.Cookies.Add((New-Object System.Net.Cookie("p.LastLoginDateTimeUtc", "Sep_08_2023_05_17_07", "/", "admin.microsoft.com"))) $session.Cookies.Add((New-Object System.Net.Cookie("s.DmnHQT", "09/08/2023 19:00:17", "/", "admin.microsoft.com"))) $session.Cookies.Add((New-Object System.Net.Cookie("s.DmnRQT", "09/08/2023 19:00:17", "/", "admin.microsoft.com"))) $session.Cookies.Add((New-Object System.Net.Cookie("s.DmnSOQT", "09/08/2023 19:00:18", "/", "admin.microsoft.com"))) $session.Cookies.Add((New-Object System.Net.Cookie("AMCV_EA76ADE95776D2EC7F000101%40AdobeOrg", "1176715910%7CMCIDTS%7C19615%7CMCMID%7C78153368502771671351739697554512531599%7CMCAID%7CNONE%7CMCOPTOUT-1694687814s%7CNONE%7CvVersion%7C5.4.0", "/", ".microsoft.com"))) $session.Cookies.Add((New-Object System.Net.Cookie("mbox", "PC#8ec11c042d71426bbd5bc070c32f1048.37_0#1728867264|session#ee311747d7314eb7905d18055bf69b3d#1694929843", "/", ".microsoft.com"))) $session.Cookies.Add((New-Object System.Net.Cookie("RootAuthToken", "AwAAABoxMi8xNi8yMDIzIDEzOjUxOjIyICswMDowMMIJMC5BUzhBOW5HenprV0hka2lnUUdueTBRcWRHZ1lBQUFBQUFQRVB6Z0FBQUFBQUFBQ3dBQzguQWdBQkFBRUFBQUF0eW9sRE9icFFRNVZ0bEk0dUdqRVBBZ0RzX3dVQTlQOF9yOGxqb1RQV29LZWQ2NnFHRGNjRU1LTFVJQlZTUk54RzVuNGw3b2VZQWxXa3EtV0hsUUczcE5ETGI2d3ppOWFUNHFrckdueHBjY1Y3aDBWdk1pUWN5bC1YVEdBNGJhS0M1YjluSHNXUFM1Vmp4WFpMczM5dWNxVzZhYXVHWUtUS0VVOFFGX0llNU5CamI3NnlSRmtHZ1pCYlVjYS1tcTlsTEhmZzFSR204WEYtSzc1aHBUUVVWdHplSUg3c3FMWXExZDNTeGk3cXBtQWZDOEpsbHlVREhKZjlndmh3VWJ0WjVrTGhPNS1OQ2hfWW9UUjRzbDhlQVJOZm13RUZaM25PWDRCUkVzdVM1VE96d3NxWHRUMDBMZEtpNXJzY1FmXzVPQUFjUmxOUGwxU1hlcUhaaUxmbTVBLWlWTnlVVnpqNUxaY3ZSNHVSVF9UcVhkREdWR2ZCUXEtLTNBRkZ1ZDJKdkJtYnVBdWh6WnVTa21xeUhIU2xQd0ZicUtsMFVjdmpGS3pxd3FKX2FQRmRJSW1rMXNXY0IyNVZ5OGdtNmFUVjNnNG9SbnVpZ1VjTkhTOW42SUwwLVVEVXROUkZvaUx6blRacmJiNm55ZFFWRTNGazFIQ2tuR21UNEpreGhfTy1rQ1RNVkd2djl0c1dsVUJtMzMtX29MenhQOFJNMlNZRENYcWR2amctU1dsZ2xRcEhGY0x3R3Z1b2tGSDEyd0JqczN0SDhWaXQ5SGRjYjN6R2pSMzJEcGJENGNvSXMyRmR1V2F5NDUya3p1bG1hekQwN1h4cDZ6VnJ3cER0UVQ0OUNiTC05REE2eEJwX1ZmQTc3c0UxeGhrUzVtNjFpajU0a0d5V1ljZi1GdlN3NlgxWjdvdzZwQ2ZXU2JzRVRCSGt6SVVMczl3YndJN1hJaWRSWGRmUHJVY3Job042aVZMZFhYOG92bGNIXzFSMGdjdG5UQ0VWMlE4V2hOMVNPYkM5djY0NXJtTGgzMWtab0gtZFd4MC1CNF9aa2FjdVpEYVR5NTB6WUV6S0dlQ3N4THNGOTZyaDJrSkJmY29Eci1LM0NjeDNNZnJyTklnY1VoY3pLZndPWkM0Z3dIWktseWJqZDc5NDVoYWhHQnN5UzNUUG1SeFF5T2FrdnBpbk85UTJpWTNGcTI0NDh3eU5ZUnp2RzdiY3VlY1FhY0htX21ZVW1hZk1jcWJzTnAtRWRHaHNTVWowaDFsZXFqRmNQVlNweDlCYkZCYUZ4WnROOXJ4X1Q0akJhR2xSZ202bVFvN0VVTFlTTzFGWDNqalJUSGZLLVllbFNJSFZValBDQzMtSDNsZVQwcndBbDFyNzBLOUNZN0VRbWo3eFBqeEtrWWxqY0g5a2ZfeHVLM3lFQlRwOGVnWV85N1lXbW1uYnZ3b2Y0LWFFbVVhU2xyLWEzVGxoaDhlUzM1Z3ZxMkRxTTRNRUY5U0p0WnhzSV9vN0lacmN6UGZaV2o3U0g5UGY2dUMxAA%3D%3D", "/", "admin.microsoft.com"))) $session.Cookies.Add((New-Object System.Net.Cookie("UserIndex", "H4sIAAAAAAAEABWMOw7CMBBETfgdgIqedsOuvXbsVFScgAvYsdNgREQQKJweu3ijkUZvGiHEqrAvNLWfS4jj9PqlxzJn%2F23veZkv6fN8p6Gd8rqsB4lSATogeyPZK%2BpZV%2F80pKA6Gg3YjjWw7Qx4ZATjRhkJvYvkN%2FV%2FW7n6PKdd9fyYlNYYIAW2wN4gBFIOcHCSOMbic9X%2B0IKQra0AAAA%3D", "/", "admin.microsoft.com"))) $session.Cookies.Add((New-Object System.Net.Cookie("OIDCAuthCookie", "yfCjU5IPAVLwmpBj6sGbqfxj5wZ5DWHOVJdL7ghJKVO50arh05rDZIt2JXeKs01xaAIyvPegl%2F6CgfxPbJbAzzkdDrvjejbrJ0%2FT%2FlNidBR49Wr8ppUggygMrBmOu6txULnL4Onu8s4nDtlXH1acEp6drFKkDJqsquBaWKjf6JZbVK4nItYVwAfb%2BXuX4R3H9OS%2BZpyeKOdUjmiof1v5%2BW7ZiQ9N7InlGzrKOk6iPRUtZ%2F6fGZM3DdtojSEIlWD%2F5bfNYiF336nyc9LXWntg2XPc4r1b%2FKThssjGo%2Fb52Y%2BtI4dEpk%2FzkEBS7aN%2BmEVwVv44lNwmevIuB3uKyU6TPuowFnAtOgOipjgbmm14oCSnhUgg5ohdpbldFJ9PqrWg%2BskUHDM1ktrs%2Ffery%2FbQ0443AasI0GedkdqIwZI9csTev3xHNql8zdnbEkOk%2BE29FjkKHn%2FaQS0%2FeHdym%2Ft2lUiIia3RtgHCrkU5Sx%2B0EHuFQYrCkbOTdCo6ZQTIqorQ5JFhnTo%2BArfVIAqrTqHQCVUSNB4jyaS7HPk3iBtQSqcQ%2FvAt8XToz3wloMQgL8wxU9f2sKuOhSFRN7HsyeNx9tUwwrrxxf3UH2b1Z75AEWZyOlfKXGx9yMPWlOo4A%2FtPagWVzeOrlDUxiVbmHjbMGq3gRZZe4x0Jyg1H4KUxxE0ikCtVZzl1y8%2BpHiPi4a8Zuz5TuN4u%2Be74F7%2Fn7HV9Qlm2x7z%2FFSqpbPUAKv%2BhyTjsGvdCiFqaSNItpAit9ZXgaWJzah3VF7vPawjcKU5c6Et2ATLnU%2BzQcL%2FUGjcB6sbB7S64yuH3LwY1OrxTJpjglMBSLAfOFYPJV%2BUU49V0kkGEnQAMBhNF2Elju2xAOvyJivJowYlL7Kpp%2FmyldJqak6E5dm09ew2gsul6u%2FTAt1CCS2XKddRzbybE9N8hKD1lS4VCVfsOyD1NDh75M7StDFxB%2Bj8QnRVbfBUxRpqYRoBKopfnfyWWdWbIbE%2FpvnRxp3tyXOL45Ay%2B9CDqY31oNIRKMiNFULmF%2Bl7WKjWDZglot7yohfecwBbKQhwkPCeX1p6AL3TMd3lto9fgWeFRTse3nqH6VFLiNfWte8cC1%2BshwB1N1uTlRi7cXjCcsAXkHVd%2BsLZUfHtbdQTCwmt9D2osulMGgZc46DBts6GFuYuqb9%2BrqXgTC%2BGCa6gCIqmxwdwIFdX00FvbS%2BK3xsoiH7FmZFmxASr%2FfBMxheiJmKv0IQt4ociak5x08IH8ONPzw2t4J5GGWTpT4vY7S51ULQ3Py1Xl1My1tRR9%2FQ7gpBA0Hb51E%2BJM6Rz3IIPO6vLcQW%2ByQbAP4P%2FZ4cISK2H%2B92yTxLrLtLBK1gNorbEbqC6YKGR%2FVLCaUax%2FHL%2BnkSpIeY8hSvcv0vt519VfVkEKb1H5PFQ41eVErO%2BppmtapukmtAUjGKT%2FQjCZBLGiEbOa9DTnIrZvrNHUEMl8gyZy0C%2BhoMWw9U6ATeNyi0O5x65rXXBHzm4OCLtqFsQ%2FVPU0I%2B8jHnS5%2BTyonI%2FlY3PYsr83Z6fS3Q8yQg%2B8CX1LGE0CRs99DmbymIO7gpcIXxsftp4Muet1VObrxD1Moc06Af%2BBZJraYtOgCuDei2z1PygqcbrBmxtXNMWDrYI9InmsuMwzw28XitJpn6bpNTrxDcC9sfkAFk4O1wBIvoTSiGUr1Tr6dqYxROOqz1nFYWmckb40DPb9ZAXlHMmc%2FCa17bo1j0GrPby%2F2ITFKpG0%2Ba2nCrhxuiEFPy9%2Bz9bqsjixISP0xs6pyny43pLp21ac8WPKXtfBcd2v9Dj5Wfh%2Bhnf79%2FaT8F3Ps2B1TzTWD6lzR7iBQgc2PE9cnb0MvEZP%2FPW%2FmEfIIqPR8CsPuBUOO8JYc%2F3CrPwwNMDUR0qVLxM%3D", "/", "admin.microsoft.com"))) $session.Cookies.Add((New-Object System.Net.Cookie("s.LoginUserTenantId", "U+ms1lH88ux27Dt5adoWQA2yiafOW1Xc3V/cvWpZJnPBwwQ2WBuze2W1/uPcJ7M3FOqJzcDA1z1Yq5kqq1C9AQCKLzrE5k0J8+HF8JSaicBWrS/jMqmKM2J/xqwdWJOIFrfatr0sBlPYp4+5b06HaQ==", "/", "admin.microsoft.com"))) $session.Cookies.Add((New-Object System.Net.Cookie("ak_bmsc", "107E5A2198C5BAAC55286ED502988D1A~000000000000000000000000000000~YAAQtDYQYHjh6o6KAQAAC7BHqBXpkLeWKfcybZoS013viOD9hP84htrgGWloObAO5uSUATmpevkEz9ssI1vsV9B/i0ZM/gK7U48hODRClPdCgMKcww/XisrHwqah6dk8suhd22e4LS0SQ708tFS9ozxiHTOlp8X5jvEeaJlRNLL5u8YrlEGHT1nCB4wY3c6F6eXOFQxLXK0M4z9unny+UhbJ2wkLaqlXHs1S0mr/d+7GsaU825nDWl+UxteoToYCdjnNdZP9Q1aLW6S3XBkhy37lNVMemRjpmW2EM4ySlBm3WyFkR3qJfh3KsSdfXfhbna1IO73M1Vk2FMU+kmhxsTH5BLMlGQTUsDbERmowlgB/qKQyc0FPJ+lRlRGeDSSsZlhTqhNnmwVvv6Gb+FA=", "/", ".microsoft.com"))) Invoke-WebRequest -UseBasicParsing -Uri "https://admin.microsoft.com/admin/api/reports/productivityScoreConfig/GetProductivityScoreConfig" ` -WebSession $session ` -Headers @{ "authority"="admin.microsoft.com" "method"="GET" "path"="/admin/api/reports/productivityScoreConfig/GetProductivityScoreConfig" "scheme"="https" "accept"="application/json, text/plain, */*" "accept-encoding"="gzip, deflate, br" "accept-language"="en-US,en;q=0.9,pl;q=0.8" "ajaxsessionkey"="RKVmBkPFeoFItafEbR6EzK1YXjonPABkGkd6MUG5qS6p5KN7kaWXxsEc8yLpECj0jKCvc+7N3CjJiLqTHyXP9Q==" "cache-control"="no-cache" "dnt"="1" "pragma"="no-cache" "referer"="https://admin.microsoft.com/?auth_upn=przemyslaw.klys%40evotec.pl&source=applauncher" "sec-ch-ua"="`"Microsoft Edge`";v=`"117`", `"Not;A=Brand`";v=`"8`", `"Chromium`";v=`"117`"" "sec-ch-ua-mobile"="?0" "sec-ch-ua-platform"="`"Windows`"" "sec-fetch-dest"="empty" "sec-fetch-mode"="cors" "sec-fetch-site"="same-origin" "x-adminapp-request"="/Settings/Services/:/Settings/L1/AdoptionScore" "x-ms-mac-appid"="414daeb8-ee33-491c-aafa-3ff6cd1a27c2" "x-ms-mac-hostingapp"="M365AdminPortal" "x-ms-mac-target-app"="MAC" "x-ms-mac-version"="host-mac_2023.9.11.3" "x-portal-routekey"="frc" } #> function Get-O365OrgAzureSpeechServices { <# .SYNOPSIS Retrieves the status of Azure Speech Services for the organization. .DESCRIPTION This function queries the Microsoft Graph API to retrieve the status of Azure Speech Services for the organization. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .EXAMPLE Get-O365OrgAzureSpeechServices -Headers $headers #> [cmdletbinding()] param( [parameter()][alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://admin.microsoft.com/admin/api/services/apps/azurespeechservices" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers [PSCustomobject] @{ AllowTheOrganizationWideLanguageModel = $Output.IsTenantEnabled } } function Get-O365OrgBingDataCollection { <# .SYNOPSIS Retrieves the Bing Data Collection settings for the organization. .DESCRIPTION This function queries the Microsoft Graph API to retrieve the Bing Data Collection settings for the organization. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .EXAMPLE Get-O365OrgBingDataCollection -Headers $headers #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://admin.microsoft.com/admin/api/settings/security/bingdatacollection" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers $Output } function Get-O365OrgBookings { <# .SYNOPSIS Retrieves the Bookings settings for the organization. .DESCRIPTION This function queries the Microsoft Graph API to retrieve the Bookings settings for the organization. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .EXAMPLE Get-O365OrgBookings -Headers $headers #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://admin.microsoft.com/admin/api/settings/apps/bookings" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers $Output } function Get-O365OrgBriefingEmail { <# .SYNOPSIS Retrieves the status of Briefing emails for the organization. .DESCRIPTION This function queries the Microsoft Graph API to retrieve the status of Briefing emails for the organization. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .EXAMPLE Get-O365OrgBriefingEmail -Headers $headers #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://admin.microsoft.com/admin/api/services/apps/briefingemail" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers if ($Output) { [PSCustomObject] @{ IsMailEnabled = $Output.IsMailEnabled IsSubscribedByDefault = $Output.IsSubscribedByDefault } } } function Get-O365OrgCalendarSharing { <# .SYNOPSIS Let your users share their calendars with people outside of your organization who have Office 365 or Exchange .DESCRIPTION Let your users share their calendars with people outside of your organization who have Office 365 or Exchange .PARAMETER Headers Authentication Token along with additional information that is created with Connect-O365Admin. If heaaders are not provided it will use the default token. .EXAMPLE Get-O365CalendarSharing .NOTES General notes #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = 'https://admin.microsoft.com/admin/api/settings/apps/calendarsharing' $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers $Output } function Get-O365OrgCommunicationToUsers { <# .SYNOPSIS Retrieves information about end user communications settings. .DESCRIPTION This function retrieves information about end user communications settings from the specified URI. .PARAMETER Headers Specifies the headers containing the authorization information. .EXAMPLE Get-O365OrgCommunicationToUsers -Headers $Headers .NOTES General notes #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = 'https://admin.microsoft.com/admin/api/settings/apps/EndUserCommunications' $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers $Output } function Get-O365OrgCortana { <# .SYNOPSIS Retrieves Cortana app information for the organization. .DESCRIPTION This function retrieves Cortana app information for the organization from the specified API endpoint using the provided headers. .PARAMETER Headers Specifies the headers containing the authorization information. .EXAMPLE Get-O365OrgCortana -Headers $Headers An example of how to retrieve Cortana app information. .NOTES General notes #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = 'https://admin.microsoft.com/admin/api/services/apps/cortana' $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers $Output } function Get-O365OrgCustomerLockbox { <# .SYNOPSIS Retrieves customer lockbox information for the organization. .DESCRIPTION This function retrieves customer lockbox information for the organization from the specified API endpoint using the provided headers. .PARAMETER Headers Specifies the headers containing the authorization information. .EXAMPLE Get-O365OrgCustomerLockbox -Headers $Headers An example of how to retrieve customer lockbox information. .NOTES General notes #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://admin.microsoft.com/admin/api/settings/security/dataaccess" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers $Output } function Get-O365OrgCustomThemes { <# .SYNOPSIS Retrieves custom themes information for the organization. .DESCRIPTION This function retrieves custom themes information for the organization from the specified API endpoint using the provided headers. .PARAMETER Headers Specifies the headers containing the authorization information. .EXAMPLE Get-O365OrgCustomThemes -Headers $Headers An example of how to retrieve custom themes information. .NOTES General notes #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://admin.microsoft.com/admin/api/Settings/company/theme/v2" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers $Output.ThemeData } function Get-O365OrgDataLocation { <# .SYNOPSIS Retrieves the data location information for the organization. .DESCRIPTION This function retrieves the data location information for the organization from the specified API endpoint using the provided headers. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .EXAMPLE Get-O365OrgDataLocation -Headers $headers #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://admin.microsoft.com/admin/api/tenant/datalocation" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers $Output } function Get-O365OrgDynamics365ConnectionGraph { <# .SYNOPSIS Retrieves Dynamics 365 Connection Graph information for the organization. .DESCRIPTION This function retrieves Dynamics 365 Connection Graph information for the organization from the specified API endpoint using the provided headers. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .EXAMPLE Get-O365OrgDynamics365ConnectionGraph -Headers $headers #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = 'https://admin.microsoft.com/admin/api/settings/apps/dcg' $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers $Output } function Get-O365OrgDynamics365CustomerVoice { <# .SYNOPSIS Retrieves Dynamics 365 Customer Voice information for the organization. .DESCRIPTION This function retrieves Dynamics 365 Customer Voice information for the organization from the specified API endpoint using the provided headers. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .EXAMPLE Get-O365OrgDynamics365CustomerVoice -Headers $headers #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [switch] $NoTranslation ) $Uri = 'https://admin.microsoft.com/admin/api/settings/apps/officeformspro' $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers if ($Output) { if ($NoTranslation) { $Output } else { [PSCustomObject] @{ # Distribution section ReduceSurveyFatigueEnabled = $Output.OverSurveyManagementEnabled # : False ReduceSurveyFatigueDays = $Output.OverSurveyManagementDays # : 0 CustomDomainEmails = $Output.CustomDomainEmails # : {} # Security section PreventPhishingAttemptsEnabled = $Output.InOrgFormsPhishingScanEnabled # : True CollectNamesEnabled = $Output.RecordIdentityByDefaultEnabled # : True RestrictSurveyAccessEnabled = $Output.RestrictSurveyAccessEnabled # : False # # not sure InOrgSurveyIncentiveEnabled = $Output.InOrgSurveyIncentiveEnabled # : False RequestType = $Output.RequestType # : 0 ValidateDomain = $Output.ValidateDomain # : } } } } function Get-O365OrgDynamics365SalesInsights { <# .SYNOPSIS Retrieves Dynamics 365 Sales Insights information for the organization. .DESCRIPTION This function retrieves Dynamics 365 Sales Insights information for the organization from the specified API endpoint using the provided headers. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .EXAMPLE Get-O365OrgDynamics365SalesInsights -Headers $headers #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = 'https://admin.microsoft.com/admin/api/settings/apps/dci' $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers $Output } function Get-O365OrgForms { <# .SYNOPSIS Retrieves information about Office Forms for the organization. .DESCRIPTION This function retrieves information about Office Forms for the organization from the specified API endpoint using the provided headers. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .EXAMPLE Get-O365OrgForms -Headers $headers #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = 'https://admin.microsoft.com/admin/api/settings/apps/officeforms/' $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers $Output } function Get-O365OrgGraphDataConnect { <# .SYNOPSIS Retrieves Graph Data Connect information for the organization. .DESCRIPTION This function retrieves Graph Data Connect information for the organization from the specified API endpoint using the provided headers. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .EXAMPLE Get-O365OrgGraphDataConnect -Headers $headers #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://admin.microsoft.com/admin/api/settings/apps/o365dataplan" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers $Output } function Get-O365OrgHelpdeskInformation { <# .SYNOPSIS Retrieves helpdesk information for the organization. .DESCRIPTION This function retrieves helpdesk information for the organization from the specified API endpoint using the provided headers. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .EXAMPLE Get-O365OrgHelpdeskInformation -Headers $headers #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://admin.microsoft.com/admin/api/Settings/company/helpdesk" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers $Output } function Get-O365OrgInstallationOptions { <# .SYNOPSIS Retrieves installation options for Microsoft 365 software. .DESCRIPTION This function retrieves installation options for Microsoft 365 software from the specified API endpoint using the provided headers. It provides details on Windows and Mac installation settings. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .PARAMETER NoTranslation Indicates whether to include translation for the installation options. .EXAMPLE Get-O365OrgInstallationOptions -Headers $headers -NoTranslation #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [switch] $NoTranslation ) $Branches = @{ "0" = 'Not applicable' "1" = "CurrentChannel" "3" = 'MonthlyEnterpriseChannel' "2" = 'SemiAnnualEnterpriseChannel' } $Uri = "https://admin.microsoft.com/admin/api/settings/apps/usersoftware" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers if ($NoTranslation) { $Output.UserSoftwareSettings } else { if ($Output.UserSoftwareSettings) { [PSCustomObject] @{ WindowsBranch = $Branches[$($Output.UserSoftwareSettings[0].Branch.ToString())] WindowsClient = $Output.UserSoftwareSettings[0].ClientVersion WindowsLastUpdate = $Output.UserSoftwareSettings[0].BranchLastUpdateTime WindowsOffice = $Output.UserSoftwareSettings[0].ServiceStatusMap.'Office (includes Skype for Business),MicrosoftOffice_ClientDownload' WindowsSkypeForBusiness = $Output.UserSoftwareSettings[0].ServiceStatusMap.'Skype for Business (Standalone),MicrosoftCommunicationsOnline'; MacBranch = $Branches[$($Output.UserSoftwareSettings[1].Branch.ToString())] MacClient = $Output.UserSoftwareSettings[1].ClientVersion MacLastUpdate = $Output.UserSoftwareSettings[1].BranchLastUpdateTime MacOffice = $Output.UserSoftwareSettings[1].ServiceStatusMap.'Office,MicrosoftOffice_ClientDownload' MacSkypeForBusiness = $Output.UserSoftwareSettings[1].LegacyServiceStatusMap.'Skype for Business (X EI Capitan 10.11 or higher),MicrosoftCommunicationsOnline' } } } } function Get-O365OrgM365Groups { <# .SYNOPSIS Provides information on how guests from outside the organization can collaborate with users in Microsoft 365 Groups. .DESCRIPTION This function retrieves settings related to guest access in Microsoft 365 Groups. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .EXAMPLE Get-O365OrgM365Groups -Headers $headers .NOTES This function provides details on guest access settings in Microsoft 365 Groups. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) #$Uri = "https://admin.microsoft.com/admin/api/settings/security/guestUserPolicy" #$Output1 = Invoke-O365Admin -Uri $Uri -Headers $Headers $Uri = "https://admin.microsoft.com/admin/api/settings/security/o365guestuser" $Output2 = Invoke-O365Admin -Uri $Uri -Headers $Headers [PSCustomObject] @{ #AllowGuestAccess = $Output1.AllowGuestAccess #AllowGuestInvitations = $Output1.AllowGuestInvitations #SitesSharingEnabled = $Output1.SitesSharingEnabled AllowGuestsAsMembers = $Output2.AllowGuestsAsMembers AllowGuestAccess = $Output2.AllowGuestAccess } } function Get-O365OrgMicrosoftEdgeSiteLists { <# .SYNOPSIS Retrieves Microsoft Edge site lists for the organization. .DESCRIPTION This function retrieves Microsoft Edge site lists for the organization from the specified API endpoint using the provided headers. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .EXAMPLE Get-O365OrgMicrosoftEdgeSiteLists -Headers $headers #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = 'https://admin.microsoft.com/fd/edgeenterprisesitemanagement/api/shard' $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers $Output } function Get-O365OrgMicrosoftTeams { <# .SYNOPSIS Retrieves Microsoft Teams settings for the organization. .DESCRIPTION This function retrieves Microsoft Teams settings for the organization from the specified API endpoint using the provided headers. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .EXAMPLE Get-O365OrgMicrosoftTeams -Headers $headers #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://admin.microsoft.com/admin/api/settings/apps/skypeteams" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers $Output <# IsSkypeTeamsLicensed : True TenantCategorySettings : {@{TenantSkuCategory=BusinessEnterprise; IsSkypeTeamsEnabled=; Meetups=; FunControl=; Messaging=}, @{TenantSkuCategory=Guest; IsSkypeTeamsEnabled=; Meetups=; FunControl=; Messaging=}} Bots : @{IsBotsEnabled=; IsSideLoadedBotsEnabled=; BotSettings=System.Object[]; IsExternalAppsEnabledByDefault=} Miscellaneous : @{IsOrganizationTabEnabled=; IsSkypeBusinessInteropEnabled=; IsTBotProactiveMessagingEnabled=} Email : @{IsEmailIntoChannelsEnabled=; RestrictedSenderList=System.Object[]} CloudStorage : @{Box=; Dropbox=; GoogleDrive=; ShareFile=} TeamsOwnedApps : @{TeamsOwnedAppSettings=System.Object[]} TenantOwnedApps : @{TenantOwnedAppSettings=System.Object[]} MigrationStates : @{EnableAppsMigration=; EnableClientSettingsMigration=; EnableMeetupsMigration=; EnableMessagingMigration=} #> } function Get-O365OrgModernAuthentication { <# .SYNOPSIS Provides information about modern authentication for Office 365. .DESCRIPTION This function retrieves details about modern authentication for Office 365 from the specified API endpoint using the provided headers. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .EXAMPLE Get-O365OrgModernAuthentication -Verbose .NOTES For more information, visit: https://admin.microsoft.com/#/Settings/Services/:/Settings/L1/ModernAuthentication #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://admin.microsoft.com/admin/api/services/apps/modernAuth" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers $Output } function Get-O365OrgMyAnalytics { <# .SYNOPSIS Retrieves MyAnalytics settings for Office 365. .DESCRIPTION This function retrieves MyAnalytics settings for Office 365 from the specified API endpoint using the provided headers. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .EXAMPLE Get-O365OrgMyAnalytics -Headers $headers #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://admin.microsoft.com/admin/api/services/apps/myanalytics" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers if ($Output) { [PSCustomObject] @{ EnableInsightsDashboard = -not $Output.IsDashboardOptedOut EnableWeeklyDigest = -not $Output.IsEmailOptedOut EnableInsightsOutlookAddIn = -not $Output.IsAddInOptedOut # IsNudgesOptedOut : False # IsWindowsSignalOptedOut : False # MeetingEffectivenessSurvey : Unavailable } } } function Get-O365OrgNews { <# .SYNOPSIS Retrieves news options for Bing in the organization. .DESCRIPTION This function retrieves news options for Bing in the organization. It can return the content enabled on a new tab and whether company information and industry are enabled. .PARAMETER Headers Authentication token and additional information created with Connect-O365Admin. .PARAMETER NoTranslation Indicates whether to skip translation of news options. .EXAMPLE Get-O365OrgNews -Headers $headers -NoTranslation .NOTES This function retrieves news options for Bing from the specified URI. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [switch] $NoTranslation ) $Uri = "https://admin.microsoft.com/admin/api/searchadminapi/news/options/Bing" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers if ($NoTranslation) { $Output } else { If ($Output) { [PSCustomObject] @{ ContentOnNewTabEnabled = $Output.NewsOptions.EdgeNTPOptions.IsOfficeContentEnabled CompanyInformationAndIndustryEnabled = $Output.NewsOptions.EdgeNTPOptions.IsShowCompanyAndIndustry } } } } function Get-O365OrgOfficeOnTheWeb { <# .SYNOPSIS Retrieves settings for Office Online apps in the organization. .DESCRIPTION This function retrieves settings for Office Online apps in the organization from the specified URI. .PARAMETER Headers Authentication token and additional information created with Connect-O365Admin. .EXAMPLE Get-O365OrgOfficeOnTheWeb -Headers $headers .NOTES This function retrieves settings for Office Online apps from the specified URI. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://admin.microsoft.com/admin/api/settings/apps/officeonline" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers $Output } function Get-O365OrgOfficeProductivity { <# .SYNOPSIS Retrieves productivity score information for the organization. .DESCRIPTION This function retrieves productivity score information for the organization from the specified URIs. .PARAMETER Headers Authentication token and additional information created with Connect-O365Admin. .EXAMPLE Get-O365OrgOfficeProductivity -Headers $headers .NOTES This function retrieves productivity score information from the specified URIs. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://admin.microsoft.com/admin/api/reports/productivityScoreCustomerOption" $Output1 = Invoke-O365Admin -Uri $Uri -Headers $Headers #$Uri = "https://admin.microsoft.com/admin/api/reports/productivityScoreConfig/GetProductivityScoreConfig" #$Output2 = Invoke-O365Admin -Uri $Uri -Headers $Headers if ($Output1) { #$Output2Json = $Output2.Output | ConvertFrom-Json $Output1Json = $Output1.Output | ConvertFrom-Json $Output = [PSCustomObject] @{ #TenantId = $Output2Json.TenantId #ProductivityScoreSignedup = $Output2Json.ProductivityScoreSignedup #SignupUserPuid = $Output2Json.SignupUserPuid #SignupTime = $Output2Json.SignupTime #ReadyTime = $Output2Json.ReadyTime ProductivityScoreOptedIn = $Output1Json.ProductivityScoreOptedIn OperationUserPuid = $Output1Json.OperationUserPuid OperationTime = $Output1Json.OperationTime } $Output } } function Get-O365OrgOrganizationInformation { <# .SYNOPSIS Retrieves organization information from the specified URI. .DESCRIPTION This function retrieves organization information from the specified URI using the provided headers. .PARAMETER Headers Authentication token and additional information for the API request. .PARAMETER NoTranslation Specifies whether to skip translation. .EXAMPLE Get-O365OrgOrganizationInformation -Headers $headers -NoTranslation .NOTES This function retrieves organization information from the specified URI. #> [alias('Get-O365OrgCompanyInformation')] [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [switch] $NoTranslation ) $Uri = "https://admin.microsoft.com/admin/api/Settings/company/profile" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers if ($NoTranslation) { $Output } else { $Output } } function Get-O365OrgPasswordExpirationPolicy { <# .SYNOPSIS Retrieves password expiration policy information from the specified URI. .DESCRIPTION This function retrieves password expiration policy information from the specified URI using the provided headers. .PARAMETER Headers Authentication token and additional information for the API request. .PARAMETER NoTranslation Specifies whether to skip translation. .EXAMPLE Get-O365OrgPasswordExpirationPolicy -Headers $headers -NoTranslation .NOTES This function retrieves password expiration policy information from the specified URI. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [switch] $NoTranslation ) $Uri = "https://admin.microsoft.com/admin/api/Settings/security/passwordpolicy" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers if ($NoTranslation) { $Output } else { [PSCustomObject] @{ PasswordNeverExpires = $Output.NeverExpire DaysBeforePasswordExpires = $Output.ValidityPeriod DaysBeforeUserNotified = $Output.NotificationDays # not shown in the GUI # MinimumValidityPeriod : 14 # MinimumNotificationDays : 1 # MaximumValidityPeriod : 730 # MaximumNotificationDays : 30 } } } function Get-O365OrgPlanner { <# .SYNOPSIS Retrieves information about Planner settings from the specified URI. .DESCRIPTION This function retrieves information about Planner settings from the specified URI using the provided headers. .PARAMETER Headers Authentication token and additional information for the API request. .EXAMPLE Get-O365OrgPlanner -Headers $headers .NOTES This function retrieves information about Planner settings from the specified URI. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://admin.microsoft.com/admin/api/services/apps/planner" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers if ($Output) { [PSCustomObject] @{ # Thos are always the same #id = $Output.id # : 1 #isPlannerAllowed = $Output.isPlannerAllowed # : True allowCalendarSharing = $Output.allowCalendarSharing # : True # GUI doesn't show that # allowTenantMoveWithDataLoss = $Output.allowTenantMoveWithDataLoss # : False # allowRosterCreation = $Output.allowRosterCreation # : True # allowPlannerMobilePushNotifications = $Output.allowPlannerMobilePushNotifications # : True } } } function Get-O365OrgPrivacyProfile { <# .SYNOPSIS Retrieves information about the organization's privacy policy. .DESCRIPTION This function retrieves information about the organization's privacy policy from the specified URI using the provided headers. .PARAMETER Headers Authentication token and additional information for the API request. .EXAMPLE Get-O365OrgPrivacyProfile -Headers $headers .NOTES This function retrieves information about the organization's privacy policy from the specified URI. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://admin.microsoft.com/admin/api/Settings/security/privacypolicy" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers $Output } function Get-O365OrgPrivilegedAccess { <# .SYNOPSIS Retrieves information about privileged access settings for the organization. .DESCRIPTION This function retrieves information about privileged access settings from the specified URI using the provided headers. .PARAMETER Headers Authentication token and additional information for the API request. .EXAMPLE Get-O365OrgPrivilegedAccess -Headers $headers .NOTES This function retrieves information about privileged access settings from the specified URI. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://admin.microsoft.com/admin/api/Settings/security/tenantLockbox" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers $Output } function Get-O365OrgProject { <# .SYNOPSIS Retrieves information about the organization's Project settings. .DESCRIPTION This function retrieves information about the organization's Project settings from the specified URI using the provided headers. .PARAMETER Headers Authentication token and additional information for the API request. .PARAMETER NoTranslation Switch to indicate whether to skip translation of output. .EXAMPLE Get-O365OrgProject -Headers $headers -NoTranslation .NOTES This function retrieves information about the organization's Project settings from the specified URI. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [switch] $NoTranslation ) $Uri = "https://admin.microsoft.com/admin/api/settings/apps/projectonline" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers if ($NoTranslation) { $Output } else { if ($Output) { [PSCustomObject] @{ RoadmapEnabled = $Output.IsRoadmapEnabled ProjectForTheWebEnabled = $Output.IsModProjEnabled } } } } function Get-O365OrgReports { <# .SYNOPSIS Retrieves organization reports configuration. .DESCRIPTION This function retrieves the organization's reports configuration from the specified URI using the provided headers. .PARAMETER Headers Authentication token and additional information for the API request. .EXAMPLE Get-O365OrgReports -Headers $headers .NOTES This function retrieves organization reports configuration from the specified URI. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://admin.microsoft.com/admin/api/reports/config/GetTenantConfiguration" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers $OutputFromJson = $Output.Output | ConvertFrom-Json $OutputFromJson } function Get-O365OrgScripts { <# .SYNOPSIS Retrieves organization scripts configuration. .DESCRIPTION This function retrieves the organization's scripts configuration from the specified URI using the provided headers. .PARAMETER Headers Authentication token and additional information for the API request. .EXAMPLE Get-O365OrgScripts -Headers $headers .NOTES This function retrieves organization scripts configuration from the specified URI. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Status = @{ '0' = 'Disabled' '1' = 'Everyone' '2' = 'SpecificGroup' } $Uri = "https://admin.microsoft.com/admin/api/settings/apps/officescripts" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers if ($Output) { [PSCustomObject] @{ # we don't show those options as they have no values # we also don't show them as there is no option in GUI #OfficeScriptsEnabled = $Output.OfficeScriptsEnabled # : #OfficeScriptsPreviewEnabled = $Output.OfficeScriptsPreviewEnabled # : EnabledOption = $Status[$($Output.EnabledOption).ToString()] # : 1 EnabledGroup = $Output.EnabledGroup # : EnabledGroupDetail = $Output.EnabledGroupDetail # : ShareOption = $Status[$($Output.ShareOption).ToString()] # : 1 ShareGroup = $Output.ShareGroup # : ShareGroupDetail = $Output.ShareGroupDetail # : UnattendedOption = $Status[$($Output.UnattendedOption).ToString()] # : 0 UnattendedGroup = $Output.UnattendedGroup # : UnattendedGroupDetail = $Output.UnattendedGroupDetail # : #TenantId = $Output.TenantId # : } } } function Get-O365OrgSendEmailNotification { <# .SYNOPSIS Retrieves organization email notification settings. .DESCRIPTION This function retrieves organization email notification settings from the specified URI using the provided headers. .PARAMETER Headers Authentication token and additional information for the API request. This parameter is required to authenticate the request and provide necessary details for the API call. .EXAMPLE Get-O365OrgSendEmailNotification -Headers $headers .NOTES This function retrieves organization email notification settings from the specified URI. It is designed to provide a comprehensive overview of the organization's email notification settings. #> [CmdletBinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://admin.microsoft.com/admin/api/Settings/company/sendfromaddress" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers if ($Output) { $Output } } function Get-O365OrgSharePoint { <# .SYNOPSIS Retrieves SharePoint organization settings. .DESCRIPTION This function retrieves SharePoint organization settings from the specified URI using the provided headers. It fetches settings such as sharing permissions, site URLs, admin URLs, and collaboration types. .PARAMETER Headers Authentication token and additional information for the API request. This parameter is required to authenticate the request and provide necessary details for the API call. .EXAMPLE Get-O365OrgSharePoint -Headers $headers .NOTES This function retrieves SharePoint organization settings from the specified URI. It is designed to provide a comprehensive overview of the organization's SharePoint settings, including sharing permissions, URLs, and collaboration types. The function uses a translation table to convert numeric collaboration types to their corresponding descriptive names. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $TranslateCollaboration = @{ '2' = 'NewAndExistingGuestsOnly' '16' = 'Anyone' '32' = 'ExistingGuestsOnly' '1' = 'OnlyPeopleInYourOrganization' } $Uri = "https://admin.microsoft.com/admin/api/settings/apps/sitessharing" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers if ($Output) { [PSCustomObject] @{ AllowSharing = $Output.AllowSharing SiteUrl = $Output.SiteUrl AdminUrl = $Output.AdminUrl RequireAnonymousLinksExpireInDays = $Output.RequireAnonymousLinksExpireInDays CollaborationType = $TranslateCollaboration[$Output.CollaborationType.ToString()] } } } function Get-O365OrgSharing { <# .SYNOPSIS Retrieves organization sharing settings. .DESCRIPTION This function retrieves organization sharing settings from the specified URI using the provided headers. .PARAMETER Headers Authentication token and additional information for the API request. .PARAMETER NoTranslation Switch to bypass translation. .EXAMPLE Get-O365OrgSharing -Headers $headers .NOTES This function retrieves organization sharing settings from the specified URI. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [switch] $NoTranslation ) $Uri = "https://admin.microsoft.com/admin/api/settings/security/guestUserPolicy" $Output1 = Invoke-O365Admin -Uri $Uri -Headers $Headers if ($NoTranslation) { $Output1 } else { # In fiddler we coudld see additional queries, but in edge/chrome not so much #$Uri = "https://admin.microsoft.com/admin/api/settings/apps/sitessharing" #$Output2 = Invoke-O365Admin -Uri $Uri -Headers $Headers #$Output2 | Format-Table # $Uri = "https://admin.microsoft.co//admin/api/settings/security/o365guestuser" # $Output3 = Invoke-O365Admin -Uri $Uri -Headers $Headers # $Output3 | Format-Table if ($Output1) { [PSCustomObject] @{ # GUI doesn't show them, so mayne lets not show them eiter #AllowGuestAccess = $Output1.AllowGuestAccess LetUsersAddNewGuests = $Output1.AllowGuestInvitations #SitesSharingEnabled = $Output1.SitesSharingEnabled #AllowSharing = $Output2.AllowSharing #SiteUrl = $Output2.SiteUrl #AdminUri = $Output2.AdminUri #RequireAnonymousLinksExpireInDays = $Output2.RequireAnonymousLinksExpireInDays #CollaborationType = $Output2.CollaborationType } } } } function Get-O365OrgSway { <# .SYNOPSIS Retrieves organization Sway settings. .DESCRIPTION This function retrieves organization Sway settings from the specified URI using the provided headers. .PARAMETER Headers Authentication token and additional information for the API request. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://admin.microsoft.com/admin/api/settings/apps/Sway" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers $Output } function Get-O365OrgToDo { <# .SYNOPSIS Retrieves organization To-Do app settings. .DESCRIPTION This function retrieves organization To-Do app settings from the specified URI using the provided headers. .PARAMETER Headers Authentication token and additional information for the API request. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://admin.microsoft.com/admin/api/services/apps/todo" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers $Output } function Get-O365OrgUserConsentApps { <# .SYNOPSIS Retrieves organization user consent apps settings. .DESCRIPTION This function retrieves organization user consent apps settings from the specified URI using the provided headers. .PARAMETER Headers Authentication token and additional information for the API request. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [switch] $Native ) $Uri = "https://graph.microsoft.com/v1.0/policies/authorizationPolicy" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers if ($null -ne $Output) { if ($Native) { $Output.defaultUserRolePermissions.permissionGrantPoliciesAssigned } else { if ($Output.defaultUserRolePermissions.permissionGrantPoliciesAssigned -is [Array]) { if ($Output.defaultUserRolePermissions.permissionGrantPoliciesAssigned -contains "ManagePermissionGrantsForSelf.microsoft-user-default-low") { [PSCustomObject] @{ UserConsentToApps = 'AllowLimited' } } elseif ($Output.defaultUserRolePermissions.permissionGrantPoliciesAssigned -contains "ManagePermissionGrantsForSelf.microsoft-user-default-legacy") { [PSCustomObject] @{ UserConsentToApps = 'AllowAll' } } else { [PSCustomObject] @{ UserConsentToApps = 'DoNotAllow' } } } else { Write-Warning "No data found. Please check the connection and try again." } } } else { Write-Warning "No data found. Please check the connection and try again." } } function Get-O365OrgUserOwnedApps { <# .SYNOPSIS Retrieves organization user owned apps settings. .DESCRIPTION This function retrieves organization user owned apps settings from the specified URIs using the provided headers. .PARAMETER Headers Authentication token and additional information for the API request. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://admin.microsoft.com/admin/api/settings/apps/store" $Output1 = Invoke-O365Admin -Uri $Uri -Headers $Headers $Uri = "https://admin.microsoft.com/admin/api/storesettings/iwpurchaseallowed" $Output2 = Invoke-O365Admin -Uri $Uri -Headers $Headers $Uri = 'https://admin.microsoft.com/fd/m365licensing/v1/policies/autoclaim' $Output4 = Invoke-O365Admin -Uri $Uri -Headers $Headers [PSCustomObject] @{ LetUsersAccessOfficeStore = $Output1 LetUsersStartTrials = $Output2 LetUsersAutoClaimLicenses = if ($Output4.tenantPolicyValue -eq 'Disabled') { $false } elseif ($Output4.tenantPolicyValue -eq 'Enabled') { $true } else { $null } <# { "policyId": "Autoclaim", "tenantPolicyValue": "Enabled", "tenantId": "ceb371f6-" } #> } } function Get-O365OrgVivaLearning { <# .SYNOPSIS Retrieves organization Viva Learning settings. .DESCRIPTION This function retrieves organization Viva Learning settings from the specified URI using the provided headers. .PARAMETER Headers Authentication token and additional information for the API request. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = 'https://admin.microsoft.com/admin/api/settings/apps/learning' $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers $Output } function Get-O365OrgWhiteboard { <# .SYNOPSIS Retrieves organization whiteboard settings. .DESCRIPTION This function retrieves organization whiteboard settings from the specified URI using the provided headers. .PARAMETER Headers Authentication token and additional information for the API request. .PARAMETER NoTranslation Switch to disable translation of telemetry data. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [switch] $NoTranslation ) $TranslateTelemetry = @{ '0' = 'Neither' '1' = 'Required' '2' = 'Optional' } $Uri = 'https://admin.microsoft.com/admin/api/settings/apps/whiteboard' $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers if ($NoTranslation) { $Output } else { if ($Output) { [PSCustomObject] @{ WhiteboardEnabled = $Output.IsEnabled DiagnosticData = $TranslateTelemetry[$Output.TelemetryPolicy.ToString()] OptionalConnectedExperiences = $Output.AreConnectedServicesEnabled BoardSharingEnabled = $Output.IsClaimEnabled OneDriveStorageEnabled = $Output.IsSharePointDefault # Not sure what this does NonTenantAccess = $Output.NonTenantAccess #LearnMoreUrl = $Output.LearnMoreUrl #ProductUrl = $Output.ProductUrl #TermsOfUseUrl = $Output.TermsOfUseUrl } } } } function Get-O365PartnerRelationship { <# .SYNOPSIS Retrieves partner relationship information based on the specified tenant ID. .DESCRIPTION This function retrieves partner relationship details for the provided tenant ID from the partner management API. .PARAMETER Headers Authentication token and additional information for the API request. .PARAMETER TenantID The ID of the tenant for which partner relationships are to be retrieved. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [string] $TenantID ) if (-not $TenantID) { if ($Headers.Tenant) { $TenantID = $Headers.Tenant } elseif ($Script:AuthorizationO365Cache.Tenant) { $TenantID = $Script:AuthorizationO365Cache.Tenant } } if ($TenantID) { $Uri = "https://admin.microsoft.com/fd/commerceMgmt/partnermanage/partners?customerTenantId=$TenantID&api-version=2.1" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers if ($Output.partners) { foreach ($Partner in $Output.partners) { [PSCustomObject] @{ id = $Partner.id #: c2248f0a name = $Partner.name #: aadRoles = Convert-AzureRole -RoleID $Partner.aadRoles # i am not 100% sure on the conversion types on different numbers so i'll disable them for now companyType = $Partner.companyType #Convert-CompanyType -CompanyType $Partner.companyType #: 4 canRemoveDap = $Partner.canRemoveDap #: True contractTypes = $Partner.contractTypes # Convert-ContractType -ContractType $Partner.contractTypes #: {3} partnerType = $Partner.partnerType #: 1 } } } } else { Write-Warning -Message "Get-O365PartnerRelationship - TenantID was not found in headers. Skipping." } } function Get-O365PasswordReset { <# .SYNOPSIS Retrieves password reset policies from the specified endpoint. .DESCRIPTION This function retrieves password reset policies from the specified API endpoint using the provided headers. .PARAMETER Headers Authentication token and additional information for the API request. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://main.iam.ad.ext.azure.com/api/PasswordReset/PasswordResetPolicies" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers $Output } function Get-O365PasswordResetIntegration { <# .SYNOPSIS Retrieves password reset integration details from the specified endpoint. .DESCRIPTION This function retrieves password reset integration details from the specified API endpoint using the provided headers. .PARAMETER Headers Authentication token and additional information for the API request. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) #$Uri = "https://main.iam.ad.ext.azure.com/api/PasswordReset/IsOnPremisesPasswordResetAvailable" $Uri = "https://main.iam.ad.ext.azure.com/api/PasswordReset/OnPremisesPasswordResetPolicies" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers if ($Output) { [PSCustomObject] @{ PasswordWritebackSupported = $Output.passwordWritebackSupported # This one doesn't change and stays enabled all the time #AccountUnlockSupported = $Output.accountUnlockSupported AccountUnlockEnabled = $Output.accountUnlockEnabled } } } function Get-O365OrgReleasePreferences { <# .SYNOPSIS Retrieves organization release preferences from the specified endpoint. .DESCRIPTION This function retrieves organization release preferences from the specified API endpoint using the provided headers. .PARAMETER Headers Authentication token and additional information for the API request. .NOTES Invoke-O365Admin function is used to make administrative calls to the Office 365 API. It handles requests for various administrative tasks. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://admin.microsoft.com/admin/api/Settings/company/releasetrack" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers $Output } function Get-O365SearchIntelligenceBingConfigurations { <# .SYNOPSIS Retrieves Bing configurations for Office 365 search intelligence. .DESCRIPTION This function retrieves Bing configurations for Office 365 search intelligence from the specified API endpoint using the provided headers. .PARAMETER Headers Authentication token and additional information for the API request. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://admin.microsoft.com/admin/api/searchadminapi/configurations" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers if ($Output) { [PSCustomObject] @{ # GUI only allowes single change to all services at once - this means if one is TRUE else is TRUE ServiceEnabled = if ($Output.People -eq $true) { $true } else { $false } People = $Output.People Groups = $Output.Groups Documents = $Output.Documents Yammer = $Output.Yammer Teams = $Output.Teams TenantState = $Output.TenantState } } } function Get-O365SearchIntelligenceBingExtension { <# .SYNOPSIS Retrieves Bing search intelligence extensions for Office 365. .DESCRIPTION This function retrieves Bing search intelligence extensions for Office 365 from the specified API endpoint using the provided headers. It checks if Bing is set as the default search engine and lists the groups for which Bing is enabled as the default search engine. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .EXAMPLE Get-O365SearchIntelligenceBingExtension -Headers $headers .NOTES This function requires a valid set of headers for authentication and authorization to access the Office 365 API. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://admin.microsoft.com/fd/bfb/api/v3/office/switch/feature" $OutputBing = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST if ($OutputBing) { [PSCustomObject] @{ BingDefaultEngine = if ($OutputBing.result -contains 'BingDefault') { $true } else { $false } #BingDefaultGroup = if ($OutputBing.result[1] -eq 'BingDefaultGroupWise') { $true } else { $false } BingDefaultGroups = if ($OutputBing.bingDefaultsEnabledGroups) { $OutputBing.bingDefaultsEnabledGroups } else { $null } } } } function Get-O365SearchIntelligenceItemInsights { <# .SYNOPSIS Retrieves item insights for Office 365 search intelligence. .DESCRIPTION This function retrieves item insights for Office 365 search intelligence from the specified API endpoint using the provided headers. .PARAMETER Headers Authentication token and additional information for the API request. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://admin.microsoft.com/fd/configgraphprivacy/ceb371f6-8745-4876-a040-69f2d10a9d1a/settings/ItemInsights" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers if ($Output) { $Return = [PSCustomObject] @{ AllowItemInsights = $Output.isEnabledInOrganization DisabledForGroup = $null DisabledForGroupID = $Output.disabledForGroup } if ($Output.DisabledForGroup) { $Group = Get-O365Group -Id $Output.DisabledForGroup -Headers $Headers if ($Group.id) { $Return.DisabledForGroup = $Group.displayName } } $Return } } function Get-O365SearchIntelligenceMeetingInsights { <# .SYNOPSIS Retrieves meeting insights for Office 365 search intelligence. .DESCRIPTION This function retrieves meeting insights for Office 365 search intelligence from the specified API endpoint using the provided headers. .PARAMETER Headers Authentication token and additional information for the API request. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers ) $Uri = "https://admin.microsoft.com/fd/ssms/api/v1.0/'3srecs'/Collection('meetinginsights')/Settings(Path=':',LogicalId='MeetingInsightsToggle')" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers if ($Output) { [PSCustomObject] @{ AllowMeetingInsights = $Output.Payload -eq 'true' } } } function Get-O365ServicePrincipal { <# .SYNOPSIS Retrieves information about Office 365 service principals based on various parameters. .DESCRIPTION This function allows you to query and retrieve service principal information from Office 365 based on different criteria such as ID, display name, service principal type, and more. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .PARAMETER Id The ID of the service principal to query. .PARAMETER DisplayName The display name of the service principal to query. .PARAMETER ServicePrincipalType The type of service principal to query. Valid values are 'Application', 'Legacy', 'SocialIdp'. .PARAMETER Property An array of properties to include in the query response. .PARAMETER Filter The filter to apply to the query. .PARAMETER GuestsOnly Switch parameter to query only guest service principals. .PARAMETER OrderBy The property to order the query results by. .EXAMPLE Get-O365ServicePrincipal -Headers $headers -DisplayName 'MyApp' -Property @('displayName', 'appId') #> [cmdletBinding(DefaultParameterSetName = "Default")] param( [parameter(ParameterSetName = 'Default')] [parameter(ParameterSetName = 'Filter')] [parameter(ParameterSetName = 'GuestsOnly')] [parameter(ParameterSetName = 'ServicePrincipalType')] [parameter(ParameterSetName = 'AppDisplayName')] [parameter(ParameterSetName = 'Id')] [parameter()][alias('Authorization')][System.Collections.IDictionary] $Headers, [parameter(ParameterSetName = 'Id')][string] $Id, [parameter(ParameterSetName = 'AppDisplayName')][string] $DisplayName, [ValidateSet('Application', 'Legacy', 'SocialIdp')][parameter(ParameterSetName = 'servicePrincipalType')][string] $ServicePrincipalType, [parameter(ParameterSetName = 'Default')] [parameter(ParameterSetName = 'Filter')] [parameter(ParameterSetName = 'GuestsOnly')] [parameter(ParameterSetName = 'ServicePrincipalType')] [parameter(ParameterSetName = 'AppDisplayName')] [parameter(ParameterSetName = 'Id')] [string[]] $Property, [parameter(ParameterSetName = 'Default')] [parameter(ParameterSetName = 'Filter')][string] $Filter, [parameter(ParameterSetName = 'GuestsOnly')][switch] $GuestsOnly, [parameter(ParameterSetName = 'GuestsOnly')] [parameter(ParameterSetName = 'Default')] [parameter(ParameterSetName = 'Filter')] [string] $OrderBy ) if ($GuestsOnly) { $Uri = 'https://graph.microsoft.com/v1.0/servicePrincipals' $QueryParameter = @{ '$Select' = $Property -join ',' '$filter' = "userType eq 'Guest'" '$orderby' = $OrderBy } } elseif ($DisplayName) { $Uri = 'https://graph.microsoft.com/v1.0/servicePrincipals' $QueryParameter = @{ '$Select' = $Property -join ',' '$filter' = "displayName eq '$DisplayName'" } } elseif ($ServicePrincipalType) { $Uri = 'https://graph.microsoft.com/v1.0/servicePrincipals' $QueryParameter = @{ '$Select' = $Property -join ',' '$filter' = "servicePrincipalType eq '$ServicePrincipalType'" } } elseif ($ID) { # Query a single group $Uri = "https://graph.microsoft.com/v1.0/servicePrincipals/$ID" $QueryParameter = @{ '$Select' = $Property -join ',' } } else { # Query multiple groups $Uri = 'https://graph.microsoft.com/v1.0/servicePrincipals' $QueryParameter = @{ '$Select' = $Property -join ',' # https://docs.microsoft.com/en-us/graph/query-parameters#filter-parameter '$filter' = $Filter '$orderby' = $OrderBy } } Remove-EmptyValue -Hashtable $QueryParameter Invoke-O365Admin -Uri $Uri -Headers $Headers -QueryParameter $QueryParameter } function Get-O365TenantID { <# .SYNOPSIS Provides the tenant ID for a given domain. .DESCRIPTION This function retrieves the tenant ID associated with a specific domain by querying the OpenID configuration endpoint. .PARAMETER Domain Specifies the domain for which to retrieve the tenant ID. .EXAMPLE Get-O365TenantID -Domain 'evotec.pl' .NOTES For more information, refer to the OpenID Connect Discovery documentation. #> [cmdletbinding()] param( [parameter(Mandatory)][alias('DomainName')][string] $Domain ) $Invoke = Invoke-RestMethod "https://login.windows.net/$Domain/.well-known/openid-configuration" -Method GET -Verbose:$false if ($Invoke) { $Invoke.userinfo_endpoint.Split("/")[3] } } function Get-O365User { <# .SYNOPSIS Provides functionality to retrieve Office 365 user information based on various parameters. .DESCRIPTION This function allows you to query and retrieve user information from Office 365 based on different criteria such as UserPrincipalName, EmailAddress, and ID. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .PARAMETER Id The ID of the user to query. .PARAMETER UserPrincipalName The UserPrincipalName of the user to query. .PARAMETER EmailAddress The email address of the user to query. .PARAMETER Property An array of properties to include in the query response. .PARAMETER Filter The filter to apply to the query. .PARAMETER GuestsOnly Switch parameter to query only guest users. .PARAMETER OrderBy The property to order the query results by. .EXAMPLE Get-O365User -Headers $headers -UserPrincipalName 'john.doe@example.com' -Property @('displayName', 'jobTitle') .NOTES For more information, visit: https://docs.microsoft.com/en-us/graph/api/user-get?view=graph-rest-1.0 #> [cmdletBinding(DefaultParameterSetName = "Default")] param( [parameter(ParameterSetName = 'Default')] [parameter(ParameterSetName = 'Filter')] [parameter(ParameterSetName = 'GuestsOnly')] [parameter(ParameterSetName = 'EmailAddress')] [parameter(ParameterSetName = 'UserPrincipalName')] [parameter(ParameterSetName = 'Id')] [parameter()][alias('Authorization')][System.Collections.IDictionary] $Headers, [parameter(ParameterSetName = 'Id')][string] $Id, [parameter(ParameterSetName = 'UserPrincipalName')][string] $UserPrincipalName, [alias('Mail')][parameter(ParameterSetName = 'EmailAddress')][string] $EmailAddress, [parameter(ParameterSetName = 'Default')] [parameter(ParameterSetName = 'Filter')] [parameter(ParameterSetName = 'GuestsOnly')] [parameter(ParameterSetName = 'EmailAddress')] [parameter(ParameterSetName = 'UserPrincipalName')] [parameter(ParameterSetName = 'Id')] [string[]] $Property, [parameter(ParameterSetName = 'Default')] [parameter(ParameterSetName = 'Filter')][string] $Filter, [parameter(ParameterSetName = 'GuestsOnly')][switch] $GuestsOnly, [parameter(ParameterSetName = 'GuestsOnly')] [parameter(ParameterSetName = 'Default')] [parameter(ParameterSetName = 'Filter')] [string] $OrderBy, [parameter(ParameterSetName = 'Default')] [parameter(ParameterSetName = 'Filter')] [parameter(ParameterSetName = 'GuestsOnly')] [parameter(ParameterSetName = 'EmailAddress')] [parameter(ParameterSetName = 'UserPrincipalName')] [parameter(ParameterSetName = 'Id')] [switch] $IncludeManager ) if ($GuestsOnly) { $Uri = 'https://graph.microsoft.com/v1.0/users' $QueryParameter = @{ '$Select' = $Property -join ',' '$filter' = "userType eq 'Guest'" '$orderby' = $OrderBy } } elseif ($UserPrincipalName) { $Uri = 'https://graph.microsoft.com/v1.0/users' $QueryParameter = @{ '$Select' = $Property -join ',' '$filter' = "userPrincipalName eq '$UserPrincipalName'" } } elseif ($EmailAddress) { $Uri = 'https://graph.microsoft.com/v1.0/users' $QueryParameter = @{ '$Select' = $Property -join ',' '$filter' = "mail eq '$EmailAddress'" } } elseif ($ID) { # Query a single group $Uri = "https://graph.microsoft.com/v1.0/users/$ID" $QueryParameter = @{ '$Select' = $Property -join ',' } } else { # Query multiple groups $Uri = 'https://graph.microsoft.com/v1.0/users' $QueryParameter = @{ '$Select' = $Property -join ',' # https://docs.microsoft.com/en-us/graph/query-parameters#filter-parameter '$filter' = $Filter '$orderby' = $OrderBy } } # https://docs.microsoft.com/en-us/graph/api/user-list-manager?view=graph-rest-1.0&tabs=http if ($IncludeManager) { $QueryParameter['$expand'] = 'manager' } Remove-EmptyValue -Hashtable $QueryParameter Invoke-O365Admin -Uri $Uri -Headers $Headers -QueryParameter $QueryParameter } function Invoke-O365Admin { <# .SYNOPSIS This function is used to make administrative calls to the Office 365 API. .DESCRIPTION This function is responsible for sending requests to the Office 365 API for administrative tasks. .PARAMETER Uri The URI endpoint for the API request. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .PARAMETER Method The HTTP method to be used for the request (GET, DELETE, POST, PATCH, PUT). .PARAMETER ContentType The content type of the request body. .PARAMETER Body The body of the request, if applicable. .PARAMETER QueryParameter The query parameters for the request. #> [cmdletBinding(SupportsShouldProcess)] param( [uri] $Uri, [alias('Authorization')][System.Collections.IDictionary] $Headers, [validateset('GET', 'DELETE', 'POST', 'PATCH', 'PUT')][string] $Method = 'GET', [string] $ContentType = "application/json; charset=UTF-8", [System.Collections.IDictionary] $Body, [System.Collections.IDictionary] $QueryParameter ) if (-not $Headers -and $Script:AuthorizationO365Cache) { # This forces a reconnect of session in case it's about to time out. If it's not timeouting a cache value is used $Headers = Connect-O365Admin -Headers $Headers } elseif ($Headers) { $Headers = Connect-O365Admin -Headers $Headers } else { Write-Warning "Invoke-O365Admin - Not connected. Please connect using Connect-O365Admin." return } if (-not $Headers) { Write-Warning "Invoke-O365Admin - Authorization error. Skipping." return } $RestSplat = @{ Method = $Method ContentType = $ContentType } if ($Uri -like '*admin.microsoft.com*') { $RestSplat['Headers'] = $Headers.HeadersO365 } elseif ($Uri -like '*graph.microsoft.com*') { $RestSplat['Headers'] = $Headers.HeadersGraph } else { $RestSplat['Headers'] = $Headers.HeadersAzure } if ($PSVersionTable.PSVersion.Major -eq 5) { $CookieContainer = [System.Net.CookieContainer]::new() $CookieContainer.MaxCookieSize = 1048576 $Session = [Microsoft.PowerShell.Commands.WebRequestSession]::new() $Session.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36 Edg/93.0.961.38" $Session.Cookies = $CookieContainer $RestSplat['WebSession'] = $Session } #$RestSplat.Headers."x-ms-mac-hosting-app" = 'M365AdminPortal' #$RestSplat.Headers."x-ms-mac-version" = 'host-mac_2021.8.16.1' #$RestSplat.Headers."sec-ch-ua" = '"Chromium";v="92", " Not A;Brand";v="99", "Microsoft Edge";v="92"' #$RestSplat.Headers."x-portal-routekey" = 'weu' #$RestSplat.Headers."x-ms-mac-appid" = 'feda2aab-4737-4646-a86c-98a7742c70e6' #$RestSplat.Headers."x-adminapp-request" = '/Settings/Services/:/Settings/L1/Whiteboard' #$RestSplat.Headers."x-ms-mac-target-app" = 'MAC' #$RestSplat.UserAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 Edg/92.0.902.73' #$RestSplat.Headers.Cookie = 'MC1=GUID=480c128a5ba04faea7df151a53bdfa9a&HASH=480c&LV=202107&V=4&LU=1627670649689' #$RestSplat.Headers."x-ms-mac-hosting-app" = 'M365AdminPortal' #$RestSplat.Headers."x-adminapp-request" = '/Settings/Services/:/Settings/L1/EndUserCommunications' #$RestSplat.Headers."Referer" = 'https://admin.microsoft.com/' #$RestSplat.Headers."AjaxSessionKey" = 'x5eAwqzbVehBOP7QHfrjpwr9eYtLiHJt7TZFj0uhUMUPQ2T7yNdA7rEgOulejHDHYM1ZyCT0pgXo96EwrfVpMA==' #$RestSplat.Headers."etag" = '1629993527.826253_3ce8143d' if ($Body) { $RestSplat['Body'] = $Body | ConvertTo-Json -Depth 5 } $RestSplat.Uri = Join-UriQuery -BaseUri $Uri -QueryParameter $QueryParameter if ($RestSplat['Body']) { $WhatIfInformation = "Invoking [$Method] " + [System.Environment]::NewLine + $RestSplat['Body'] + [System.Environment]::NewLine } else { $WhatIfInformation = "Invoking [$Method] " } try { Write-Verbose "Invoke-O365Admin - $($WhatIfInformation)over URI $($RestSplat.Uri)" if ($Method -eq 'GET') { # We use separate check because WHATIF would sometimes trigger when GET was used inside a SET $OutputQuery = Invoke-RestMethod @RestSplat -Verbose:$false if ($null -ne $OutputQuery) { if ($OutputQuery -is [bool]) { $OutputQuery } elseif ($OutputQuery -is [array]) { $Properties = $OutputQuery | Select-Properties -ExcludeProperty '@odata.context', '@odata.id', '@odata.type', 'Length' -WarningAction SilentlyContinue -WarningVariable varWarning if (-not $varWarning) { $OutputQuery | Select-Object -Property $Properties } } elseif ($OutputQuery -is [string]) { if ($OutputQuery) { $Properties = $OutputQuery | Select-Properties -ExcludeProperty '@odata.context', '@odata.id', '@odata.type', 'Length' -WarningAction SilentlyContinue -WarningVariable varWarning if (-not $varWarning) { $OutputQuery | Select-Object -Property $Properties } } } elseif ($OutputQuery -is [PSCustomObject]) { if ($OutputQuery.PSObject.Properties.Name -contains 'value') { $Properties = $OutputQuery.value | Select-Properties -ExcludeProperty '@odata.context', '@odata.id', '@odata.type', 'Length' -WarningAction SilentlyContinue -WarningVariable varWarning if (-not $varWarning) { $OutputQuery.value | Select-Object -Property $Properties } } else { $Properties = $OutputQuery | Select-Properties -ExcludeProperty '@odata.context', '@odata.id', '@odata.type', 'Length' -WarningAction SilentlyContinue -WarningVariable varWarning if (-not $varWarning) { $OutputQuery | Select-Object -Property $Properties } } } else { Write-Warning -Message "Invoke-O365Admin - Type $($OutputQuery.GetType().Name) potentially unsupported." $OutputQuery } } if ($OutputQuery -isnot [array]) { if ($OutputQuery.'@odata.nextLink') { $RestSplat.Uri = $OutputQuery.'@odata.nextLink' if ($RestSplat.Uri) { # We must remove websession parameter because Invoke-o365admin doesn't have it and i don't want to add it to the code # it will set it self anyways $RestSplat.Remove('WebSession') # We need to reset the headers to full header, rather than the one that was used to invoke the previous call $RestSplat.Headers = $Headers # Not sure if this is best/fastest way to do it, but it works # It's a bit better than saving it to variable and releasing everything later on as it can be used in pipeline Invoke-O365Admin @RestSplat | ForEach-Object { if ($null -ne $_) { $_ } } #if ($null -ne $MoreData) { # $MoreData #} } } } } else { if ($PSCmdlet.ShouldProcess($($RestSplat.Uri), $WhatIfInformation)) { #$CookieContainer = [System.Net.CookieContainer]::new() #$CookieContainer.MaxCookieSize = 8096 $OutputQuery = Invoke-RestMethod @RestSplat -Verbose:$false if ($Method -in 'POST', 'PUT') { if ($null -ne $OutputQuery) { $OutputQuery } } else { return $true } } } } catch { if ($PSBoundParameters.ErrorAction -eq 'Stop') { Write-Error $_ return } $RestError = $_.ErrorDetails.Message $RestMessage = $_.Exception.Message if ($RestError) { try { $ErrorMessage = ConvertFrom-Json -InputObject $RestError -ErrorAction Stop $ErrorText = $ErrorMessage.error.message # Write-Warning -Message "Invoke-O365Admin - [$($ErrorMessage.error.code)] $($ErrorMessage.error.message), exception: $($_.Exception.Message)" Write-Warning -Message "Invoke-O365Admin - Error: $($RestMessage) $($ErrorText)" } catch { $ErrorText = '' Write-Warning -Message "Invoke-O365Admin - Error: $($RestMessage)" } } else { Write-Warning -Message "Invoke-O365Admin - Error: $($_.Exception.Message)" } if ($_.ErrorDetails.RecommendedAction) { Write-Warning -Message "Invoke-O365Admin - Recommended action: $RecommendedAction" } if ($Method -notin 'GET', 'POST') { return $false } } } function New-O365License { <# .SYNOPSIS Helper cmdlet to create a new O365 license that is used in Set-O365AzureGroupLicenses cmdlet. .DESCRIPTION Helper cmdlet to create a new O365 license that is used in Set-O365AzureGroupLicenses cmdlet. .PARAMETER LicenseName LicenseName to assign. Can be used instead of LicenseSKUID .PARAMETER LicenseSKUID LicenseSKUID to assign. Can be used instead of LicenseName .PARAMETER EnabledServicesDisplayName Specifies the display names of services to enable. .PARAMETER EnabledServicesName Specifies the names of services to enable. .PARAMETER DisabledServicesDisplayName Specifies the display names of services to disable. .PARAMETER DisabledServicesName Specifies the names of services to disable. .EXAMPLE Set-O365GroupLicenses -GroupDisplayName 'Test-Group-TestEVOTECPL' -Licenses @( New-O365License -LicenseName 'Office 365 E3' -Verbose New-O365License -LicenseName 'Enterprise Mobility + Security E5' -Verbose ) -Verbose -WhatIf .EXAMPLE Set-O365GroupLicenses -GroupDisplayName 'Test-Group-TestEVOTECPL' -Licenses @( New-O365License -LicenseName 'Office 365 E3' -Verbose -DisabledServicesDisplayName 'Microsoft Kaizala Pro', 'Whiteboard (Plan 2)' New-O365License -LicenseName 'Enterprise Mobility + Security E5' -Verbose -EnabledServicesDisplayName 'Azure Information Protection Premium P2', 'Microsoft Defender for Identity' ) -Verbose -WhatIf .NOTES General notes #> [cmdletbinding(DefaultParameterSetName = 'ServiceDisplayNameEnable')] param( [string] $LicenseName, [string] $LicenseSKUID, [Parameter(ParameterSetName = 'ServiceDisplayNameEnable')][string[]] $EnabledServicesDisplayName, [Parameter(ParameterSetName = 'ServiceNameEnable')][string[]] $EnabledServicesName, [Parameter(ParameterSetName = 'ServiceDisplayNameDisable')][string[]] $DisabledServicesDisplayName, [Parameter(ParameterSetName = 'ServiceNameDisable')][string[]] $DisabledServicesName ) if ($LicenseName) { $ServicePlans = Get-O365AzureLicenses -ServicePlans -IncludeLicenseDetails -LicenseName $LicenseName } elseif ($LicenseSKUID) { $ServicePlans = Get-O365AzureLicenses -ServicePlans -IncludeLicenseDetails -LicenseSKUID $LicenseSKUID } else { return } if ($ServicePlans) { if ($EnabledServicesDisplayName -or $EnabledServicesName -or $DisabledServicesDisplayName -or $DisabledServicesName) { [Array] $DisabledServicePlans = foreach ($Plan in $ServicePlans) { if ($EnabledServicesDisplayName) { if ($Plan.ServiceDisplayName -notin $EnabledServicesDisplayName) { $Plan.serviceName } } elseif ($EnabledServicesName) { if ($Plan.ServiceName -notin $EnabledServicesName) { $Plan.serviceName } } elseif ($DisabledServicesDisplayName) { if ($Plan.ServiceDisplayName -in $DisabledServicesDisplayName) { $Plan.serviceName } } elseif ($DisabledServicesName) { if ($Plan.ServiceName -in $DisabledServicesName) { $Plan.serviceName } } } } else { $DisabledServicePlans = @() } if ($ServicePlans[0].LicenseSKUID) { [ordered] @{ accountSkuId = $ServicePlans[0].LicenseSKUID disabledServicePlans = if ($DisabledServicePlans.Count -eq 0) { , @() } else { $DisabledServicePlans } } } else { Write-Warning "New-O365License - No LicenseSKUID found. Skipping" } } } function Set-O365AzureEnterpriseAppsGroupConsent { <# .SYNOPSIS Provides functionality to set group-specific consent for enterprise apps in Azure Active Directory. .DESCRIPTION This function allows administrators to configure group-specific consent for enterprise apps in Azure Active Directory. .PARAMETER Headers Specifies the headers for the API request, typically including authorization tokens. .PARAMETER EnableGroupSpecificConsent Specifies whether to enable group-specific consent. .PARAMETER GroupId The ID of the group for which to set consent. .PARAMETER GroupName The display name of the group for which to set consent. .PARAMETER BlockUserConsentForRiskyApps Specifies whether to block user consent for risky apps. .PARAMETER EnableAdminConsentRequests Specifies whether to enable admin consent requests. .EXAMPLE An example of how to use this function: Set-O365AzureEnterpriseAppsGroupConsent -Headers $headers -EnableGroupSpecificConsent $true -GroupId "12345" -BlockUserConsentForRiskyApps $true -EnableAdminConsentRequests $false .NOTES Please ensure that: - Group-specific consent can be set using either GroupId or GroupName parameter. #> # https://portal.azure.com/#blade/Microsoft_AAD_IAM/ConsentPoliciesMenuBlade/UserSettings [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [Parameter()][bool] $EnableGroupSpecificConsent, [Parameter()][string] $GroupId, [Parameter()][string] $GroupName, # Other options [Parameter()][bool] $BlockUserConsentForRiskyApps, [Parameter()][bool] $EnableAdminConsentRequests ) $Uri = 'https://graph.microsoft.com/beta/settings/e0953218-a490-4c92-a975-ab724a6cfb07' $CurrentSettings = Get-O365AzureEnterpriseAppsGroupConsent -Headers $Headers if ($CurrentSettings) { [string] $EnableSpecific = if ($PSBoundParameters.ContainsKey('EnableGroupSpecificConsent')) { $EnableGroupSpecificConsent.ToString().ToLower() } else { $CurrentSettings.EnableGroupSpecificConsent.ToString().ToLower() } if ($PSBoundParameters.ContainsKey('EnableGroupSpecificConsent')) { # We only set group if EnableGroupSpecificConsent is used if ($GroupId) { $Group = $GroupId } elseif ($GroupName) { $AskForGroup = Get-O365Group -DisplayName $GroupName -Headers $Headers if ($AskForGroup.Id) { $Group = $AskForGroup.Id if ($Group -isnot [string]) { Write-Warning -Message "Set-O365AzureEnterpriseAppsGroupConsent - GroupName couldn't be translated to single ID. " foreach ($G in $AskForGroup) { Write-Warning -Message "Group DisplayName: $($G.DisplayName) | Group ID: $($G.ID)" } return } } else { Write-Warning -Message "Set-O365AzureEnterpriseAppsGroupConsent - GroupName couldn't be translated to ID. Skipping." return } } else { $Group = '' } } else { # We read the current group $Group = $CurrentSettings.ConstrainGroupSpecificConsentToMembersOfGroupId } [string] $BlockUserConsent = if ($PSBoundParameters.ContainsKey('BlockUserConsentForRiskyApps')) { $BlockUserConsentForRiskyApps.ToString().ToLower() } else { $CurrentSettings.BlockUserConsentForRiskyApps.ToString().ToLower() } [string] $AdminConsent = if ($PSBoundParameters.ContainsKey('EnableAdminConsentRequests')) { $EnableAdminConsentRequests.ToString().ToLower() } else { $CurrentSettings.EnableAdminConsentRequests.ToString().ToLower() } $Body = @{ values = @( [ordered] @{ "name" = "EnableGroupSpecificConsent"; "value" = $EnableSpecific } [ordered] @{ "name" = "BlockUserConsentForRiskyApps"; "value" = $BlockUserConsent } [ordered] @{ "name" = "EnableAdminConsentRequests"; "value" = $AdminConsent } [ordered] @{ "name" = "ConstrainGroupSpecificConsentToMembersOfGroupId"; value = $Group } ) } $null = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method PATCH -Body $Body } } function Set-O365AzureEnterpriseAppsUserConsent { <# .SYNOPSIS Configures user consent settings for Azure enterprise applications. .DESCRIPTION This function allows administrators to configure user consent settings for Azure enterprise applications. .PARAMETER Headers Specifies the headers for the API request, typically including authorization tokens. .PARAMETER PermissionGrantPoliciesAssigned Specifies the permission grant policies assigned for user consent. .EXAMPLE An example of how to use this function: Set-O365AzureEnterpriseAppsUserConsent -Headers $headers -PermissionGrantPoliciesAssigned 'AllowUserConsentForApps' .NOTES For more information, visit: https://portal.azure.com/#blade/Microsoft_AAD_IAM/ConsentPoliciesMenuBlade/UserSettings #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [Parameter(Mandatory)][string][ValidateSet('AllowUserConsentForApps', 'AllowUserConsentForSelectedPermissions', 'DoNotAllowUserConsent')] $PermissionGrantPoliciesAssigned ) $Uri = 'https://graph.microsoft.com/v1.0/policies/authorizationPolicy' $Convert = Convert-AzureEnterpriseAppsUserConsent -PermissionsGrantPoliciesAssigned $PermissionGrantPoliciesAssigned -Reverse $Body = @{ defaultUserRolePermissions = [ordered] @{ permissionGrantPoliciesAssigned = if ($Convert) { , @($Convert) } else { , @() } } } if ($Body) { $null = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method PATCH -Body $Body } } function Set-O365AzureEnterpriseAppsUserSettings { <# .SYNOPSIS Configures user settings for Azure enterprise applications. .DESCRIPTION This function allows administrators to configure user settings for Azure enterprise applications. .PARAMETER Headers Specifies the headers for the API request, typically including authorization tokens. .PARAMETER UsersCanConsentAppsAccessingData Specifies whether users can consent to apps accessing company data. .PARAMETER UsersCanAddGalleryAppsToMyApp Specifies whether users can add gallery apps to their applications. .PARAMETER UsersCanOnlySeeO365AppsInPortal Specifies whether users can only see Office 365 apps in the portal. .EXAMPLE An example of how to use this function: Set-O365AzureEnterpriseAppsUserSettings -Headers $headers -UsersCanConsentAppsAccessingData $true -UsersCanAddGalleryAppsToMyApp $false -UsersCanOnlySeeO365AppsInPortal $true .NOTES Please keep in mind that: - Users can consent to apps accessing company data for the groups they own -> can be set using Set-O3465AzureEnterpriseAppsGroupConsent #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [nullable[bool]] $UsersCanConsentAppsAccessingData, [nullable[bool]] $UsersCanAddGalleryAppsToMyApp, [nullable[bool]] $UsersCanOnlySeeO365AppsInPortal ) $Uri = 'https://main.iam.ad.ext.azure.com/api/EnterpriseApplications/UserSettings' # contrary to most of the cmdlets it seem if you provide null as values not filled in, nothing is changed # Body "{`"usersCanAllowAppsToAccessData`":false,`"usersCanAddGalleryApps`":null,`"hideOffice365Apps`":null}" $Body = @{ usersCanAllowAppsToAccessData = $UsersCanConsentAppsAccessingData usersCanAddGalleryApps = $UsersCanAddGalleryAppsToMyApp hideOffice365Apps = $UsersCanOnlySeeO365AppsInPortal } # But we're going to remove those empty entries anyways Remove-EmptyValue -Hashtable $Body if ($Body.Keys.Count -gt 0) { $null = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method PATCH -Body $Body } } function Set-O365AzureEnterpriseAppsUserSettingsAdmin { <# .SYNOPSIS Enables or Disables user consent to enterprise apps in Azure. .DESCRIPTION This function allows administrators to enable or disable user consent to enterprise apps in Azure. When enabled, users can consent to apps accessing their data. When disabled, only admins can consent to apps. .PARAMETER Headers Specifies the headers for the API request. Typically includes authorization tokens. .PARAMETER UserConsentToAppsEnabled Indicates whether user consent to enterprise apps is enabled. .EXAMPLE $headers = @{Authorization = "Bearer your_token"} Set-O365AzureEnterpriseAppsUserSettingsAdmin -Headers $headers -UserConsentToAppsEnabled $true This example enables user consent to enterprise apps. .LINK https://main.iam.ad.ext.azure.com/api/RequestApprovals/V2/PolicyTemplates #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [parameter(Mandatory)][bool] $UserConsentToAppsEnabled ) $Uri = "https://main.iam.ad.ext.azure.com/api/RequestApprovals/V2/PolicyTemplates" #-Body "{`"id`":null,`"requestExpiresInDays`":30,`"notificationsEnabled`":true,` #"remindersEnabled`":true,`"approversV2`":{`"user`":[`"e6a8f1cf-0874-4323-a12f-2bf51bb6dfdd`"],`"group`":[],`"role`":[]}}" #$Body = @{ # Enabled = $UserConsentToAppsEnabled #} #$null = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body } function Set-O365AzureExternalCollaborationRestrictions { <# .SYNOPSIS Configures external collaboration restrictions for Office 365 Azure. .DESCRIPTION This function allows administrators to configure various restrictions related to external collaboration in Office 365 Azure. It includes options for managing collaboration domains and settings. .PARAMETER Headers Specifies the headers for the API request. Typically includes authorization tokens. .PARAMETER CollaborationRestrictions Specifies the type of collaboration restrictions to be applied. Valid values are 'AllowAnyDomains', 'AllowSpecifiedDomains', 'DisallowSpecifiedDomains'. .PARAMETER TargetedDomains Specifies the domains to be targeted. This parameter is used when CollaborationRestrictions is set to 'AllowSpecifiedDomains' or 'DisallowSpecifiedDomains'. .EXAMPLE $headers = @{Authorization = "Bearer your_token"} Set-O365AzureExternalCollaborationRestrictions -Headers $headers -CollaborationRestrictions "AllowAnyDomains" This example allows any domains for external collaboration. .LINK https://main.iam.ad.ext.azure.com/api/B2B/b2bPolicy #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [ValidateSet('AllowAnyDomains', 'AllowSpecifiedDomains', 'DisallowSpecifiedDomains')][string] $CollaborationRestrictions, [string[]] $TargetedDomains ) $Uri = 'https://main.iam.ad.ext.azure.com/api/B2B/b2bPolicy' # $Body = @{ # targetedDomains = $UsersCanConsentAppsAccessingData # isAllowlist = $UsersCanAddGalleryAppsToMyApp # hasListEntries = $UsersCanOnlySeeO365AppsInPortal # otpEnabled = $otpEnabled # adminConsentedForUsersIntoTenantIds = @() # noAADConsentForUsersFromTenantsIds = @() # } if ($CollaborationRestrictions -eq 'AllowAnyDomains') { $Body = @{ targetedDomains = @() isAllowlist = $true #hasListEntries = $true #otpEnabled = $false #adminConsentedForUsersIntoTenantIds = @() #noAADConsentForUsersFromTenantsIds = @() } } elseif ($CollaborationRestrictions -eq 'AllowSpecifiedDomains') { $Body = @{ targetedDomains = @($TargetedDomains) isAllowlist = $true #hasListEntries = $true #otpEnabled = $false #adminConsentedForUsersIntoTenantIds = @() #noAADConsentForUsersFromTenantsIds = @() } } elseif ($CollaborationRestrictions -eq 'DisallowSpecifiedDomains') { $Body = @{ targetedDomains = @($TargetedDomains) isAllowlist = $false #hasListEntries = $true #otpEnabled = $false #adminConsentedForUsersIntoTenantIds = @() #noAADConsentForUsersFromTenantsIds = @() } } #Remove-EmptyValue -Hashtable $Body if ($Body.Keys.Count -gt 0) { $null = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body } } function Set-O365AzureExternalCollaborationSettings { <# .SYNOPSIS Configures external collaboration settings for Office 365 Azure. .DESCRIPTION This function allows administrators to configure various settings related to external collaboration in Office 365 Azure. It includes options for managing invitations, subscription sign-ups, self-service password reset (SSPR), and more. .PARAMETER Headers Specifies the headers for the API request. Typically includes authorization tokens. .PARAMETER AllowInvitesFrom Specifies who can send invitations to external users. Valid values are 'none', 'adminsAndGuestInviters', 'adminsGuestInvitersAndAllMembers', 'everyone'. .PARAMETER AllowedToSignUpEmailBasedSubscriptions Indicates whether users are allowed to sign up for email-based subscriptions. .PARAMETER AllowedToUseSSPR Indicates whether users are allowed to use Self-Service Password Reset. .PARAMETER AllowEmailVerifiedUsersToJoinOrganization Indicates whether email verified users are allowed to join the organization. .PARAMETER BlockMsolPowerShell Indicates whether to block the use of MSOnline PowerShell module. .PARAMETER DisplayName The display name for the settings. .PARAMETER Description A description of the settings. .PARAMETER GuestUserRole Specifies the role of a guest user. Valid values are 'User', 'GuestUser', 'RestrictedUser'. .PARAMETER AllowedToCreateApps Indicates whether users are allowed to create applications. .PARAMETER AllowedToCreateSecurityGroups Indicates whether users are allowed to create security groups. .PARAMETER AllowedToReadOtherUsers Indicates whether users are allowed to read other users' profiles. .PARAMETER PermissionGrantPoliciesAssigned Specifies the permission grant policies assigned to the user. .EXAMPLE $headers = @{Authorization = "Bearer your_token"} Set-O365AzureExternalCollaborationSettings -Headers $headers -AllowInvitesFrom "everyone" -AllowedToSignUpEmailBasedSubscriptions $true -AllowedToUseSSPR $true -AllowEmailVerifiedUsersToJoinOrganization $false -BlockMsolPowerShell $false -DisplayName "External Collaboration Policy" -Description "Policy for managing external collaboration." -GuestUserRole "GuestUser" -AllowedToCreateApps $true -AllowedToCreateSecurityGroups $true -AllowedToReadOtherUsers $false -PermissionGrantPoliciesAssigned @("Policy1", "Policy2") .NOTES Ensure that you have the necessary permissions to invoke this command. #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [ValidateSet('none', 'adminsAndGuestInviters', 'adminsGuestInvitersAndAllMembers', 'everyone')][string] $AllowInvitesFrom, [System.Nullable[bool]] $AllowedToSignUpEmailBasedSubscriptions, [System.Nullable[bool]] $AllowedToUseSSPR, [System.Nullable[bool]] $AllowEmailVerifiedUsersToJoinOrganization, [System.Nullable[bool]] $BlockMsolPowerShell, [string] $DisplayName, [string] $Description, [ValidateSet('User', 'GuestUser', 'RestrictedUser')][string] $GuestUserRole, [System.Nullable[bool]] $AllowedToCreateApps, [System.Nullable[bool]] $AllowedToCreateSecurityGroups, [System.Nullable[bool]] $AllowedToReadOtherUsers, [Array] $PermissionGrantPoliciesAssigned ) $GuestUserRoleIDs = @{ 'User' = 'a0b1b346-4d3e-4e8b-98f8-753987be4970' 'GuestUser' = '10dae51f-b6af-4016-8d66-8c2a99b929b3' 'RestrictedUser' = '2af84b1e-32c8-42b7-82bc-daa82404023b' } if ($GuestUserRole) { $GuestUserRoleID = $GuestUserRoleIDs[$GuestUserRole] } if ($AllowInvitesFrom) { # This translation is to make sure the casing is correct as it may be given by user in different way if ($AllowInvitesFrom -eq 'none') { $AllowInvitesFrom = 'none' } elseif ($AllowInvitesFrom -eq 'adminsAndGuestInviters') { $AllowInvitesFrom = 'adminsAndGuestInviters' } elseif ($AllowInvitesFrom -eq 'adminsGuestInvitersAndAllMembers') { $AllowInvitesFrom = 'adminsGuestInvitersAndAllMembers' } elseif ($AllowInvitesFrom -eq 'everyone') { $AllowInvitesFrom = 'everyone' } } $Uri = 'https://graph.microsoft.com/v1.0/policies/authorizationPolicy' $Body = @{ allowInvitesFrom = $AllowInvitesFrom # : adminsAndGuestInviters allowedToSignUpEmailBasedSubscriptions = $AllowedToSignUpEmailBasedSubscriptions # : True allowedToUseSSPR = $AllowedToUseSSPR # : True allowEmailVerifiedUsersToJoinOrganization = $AllowEmailVerifiedUsersToJoinOrganization # : False blockMsolPowerShell = $BlockMsolPowerShell # : False displayName = $DisplayName # : Authorization Policy description = $Description # : Used to manage authorization related settings across the company. guestUserRoleId = $GuestUserRoleId # : a0b1b346-4d3e-4e8b-98f8-753987be4970 defaultUserRolePermissions = [ordered] @{ allowedToCreateApps = $AllowedToCreateApps allowedToCreateSecurityGroups = $AllowedToCreateSecurityGroups allowedToReadOtherUsers = $AllowedToReadOtherUsers permissionGrantPoliciesAssigned = $PermissionGrantPoliciesAssigned } } Remove-EmptyValue -Hashtable $Body -Recursive -Rerun 2 if ($Body) { $null = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method PATCH -Body $Body #$Output } } function Set-O365AzureGroupExpiration { <# .SYNOPSIS Sets the expiration settings for Office 365 Azure groups. .DESCRIPTION This function configures the lifecycle management settings for Office 365 Azure groups, including setting the group lifetime, specifying which groups are managed, and configuring admin notification emails. .PARAMETER Headers Specifies the headers for the API request. Typically includes authorization tokens. .PARAMETER GroupLifeTime Specifies the lifetime of the group in days. Accepts 180 or 365 days, or a custom value. .PARAMETER ExpirationEnabled Determines the scope of groups for which expiration is enabled. Valid values are 'None', 'Selected', 'All'. .PARAMETER AdminNotificationEmails Specifies the email addresses for sending notifications about group expiration events. .PARAMETER ExpirationGroups Specifies the display names of groups for which expiration settings are to be applied. This parameter is used when ExpirationEnabled is set to 'Selected'. .PARAMETER ExpirationGroupsID Specifies the IDs of groups for which expiration settings are to be applied. This parameter is used when ExpirationEnabled is set to 'Selected'. .EXAMPLE $Headers = @{Authorization = "Bearer your_token"} Set-O365AzureGroupExpiration -Headers $Headers -GroupLifeTime 365 -ExpirationEnabled 'Selected' -AdminNotificationEmails 'admin@example.com' -ExpirationGroups @('Group1', 'Group2') This example sets the group expiration for 'Group1' and 'Group2' with a lifetime of 365 days, where only selected groups are managed, and notifications are sent to 'admin@example.com'. .LINK https://main.iam.ad.ext.azure.com/api/Directories/LcmSettings #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [nullable[int]] $GroupLifeTime, [string][ValidateSet('None', 'Selected', 'All')] $ExpirationEnabled, [string] $AdminNotificationEmails, [Array] $ExpirationGroups, [Array] $ExpirationGroupsID ) $Uri = 'https://main.iam.ad.ext.azure.com/api/Directories/LcmSettings' $CurrentSettings = Get-O365AzureGroupExpiration -Headers $Headers -NoTranslation if ($null -ne $GroupLifeTime) { # if group lifetime is defined we need to build 2 values if ($GroupLifeTime -eq 180) { $expiresAfterInDays = 0 $groupLifetimeCustomValueInDays = 0 } elseif ($GroupLifeTime -eq 365) { $expiresAfterInDays = 1 $groupLifetimeCustomValueInDays = 0 } else { $expiresAfterInDays = 2 $groupLifetimeCustomValueInDays = $GroupLifeTime } } else { # if it's not defined we need to get current values $expiresAfterInDays = $CurrentSettings.expiresAfterInDays $groupLifetimeCustomValueInDays = $CurrentSettings.groupLifetimeCustomValueInDays } if ($ExpirationEnabled -eq 'None') { $ManagedGroupTypes = 2 } elseif ($ExpirationEnabled -eq 'Selected') { $ManagedGroupTypes = 1 } elseif ($ExpirationEnabled -eq 'All') { $ManagedGroupTypes = 0 } else { $ManagedGroupTypes = $CurrentSettings.managedGroupTypes } if (-not $AdminNotificationEmails) { $AdminNotificationEmails = $CurrentSettings.adminNotificationEmails } if ($ExpirationGroups) { [Array] $GroupsID = foreach ($Ex in $ExpirationGroups) { $GroupFound = Get-O365Group -DisplayName $Ex -Headers $Headers if ($GroupFound.Id) { $GroupFound.Id } } if ($GroupsID.Count -gt 0) { $groupIdsToMonitorExpirations = if ($GroupsID.Count -in 0, 1) { , @($GroupsID) } else { $GroupsID } } else { Write-Warning -Message "Set-O365AzureGroupExpiration - Couldn't find any groups provided in ExpirationGroups. Skipping" return } } elseif ($ExpirationGroupsID) { $groupIdsToMonitorExpirations = if ($ExpirationGroupsID.Count -in 0, 1) { , @($ExpirationGroupsID) } else { $ExpirationGroupsID } } else { $groupIdsToMonitorExpirations = if ($CurrentSettings.groupIdsToMonitorExpirations.count -in 0, 1) { , @($CurrentSettings.groupIdsToMonitorExpirations) } else { $CurrentSettings.groupIdsToMonitorExpirations } } $Body = [ordered] @{ expiresAfterInDays = $expiresAfterInDays groupLifetimeCustomValueInDays = $groupLifetimeCustomValueInDays managedGroupTypesEnum = $CurrentSettings.managedGroupTypesEnum managedGroupTypes = $ManagedGroupTypes adminNotificationEmails = $AdminNotificationEmails groupIdsToMonitorExpirations = $groupIdsToMonitorExpirations policyIdentifier = $CurrentSettings.policyIdentifier } $null = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method PUT -Body $Body } function Set-O365AzureGroupM365 { <# .SYNOPSIS Enables or Disables Microsoft 365 Groups - "Users can create Microsoft 365 groups in Azure portals, API or PowerShell" .DESCRIPTION Enables or Disables Microsoft 365 Groups - "Users can create Microsoft 365 groups in Azure portals, API or PowerShell" .PARAMETER Headers Authorization header as created by Connect-O365Admin. If not provided the function will try to fetch it from the current execution context. .PARAMETER AllowedToCreateM365Groups Enables or disables "Users can create Microsoft 365 groups in Azure portals, API or PowerShell" .EXAMPLE Set-O365AzureGroupM365 -Verbose -AllowedToCreateM365Groups $true -WhatIf .NOTES https://portal.azure.com/#blade/Microsoft_AAD_IAM/GroupsManagementMenuBlade/General #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [parameter(Mandatory)][bool] $AllowedToCreateM365Groups ) $CurrentSettings = Get-O365AzureGroupNamingPolicy -NoTranslation -Headers $Headers if ($CurrentSettings.id) { $Uri = "https://graph.microsoft.com/beta/settings/$($CurrentSettings.id)" [Array] $Values = foreach ($Policy in $CurrentSettings.values) { if ($Policy.Name -eq 'EnableGroupCreation') { [PSCustomObject] @{ name = 'EnableGroupCreation' value = $AllowedToCreateM365Groups.ToString() } } else { $Policy } } $Body = @{ values = $Values } $null = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method PATCH -Body $Body } } function Set-O365AzureGroupNamingPolicy { <# .SYNOPSIS Sets new prefix/suffix for M365 groups naming policy. .DESCRIPTION Sets new prefix/suffix for M365 groups naming policy. The Microsoft 365 groups naming policy allows you to add a specific prefix and/or suffix to the group name and alias of any Microsoft 365 group created by users. For example: <Finance> <group> <Seattle> .PARAMETER Headers Authorization header as created by Connect-O365Admin. If not provided the function will try to fetch it from the current execution context. .PARAMETER Prefix Sets or updates the prefix for the group naming policy. One can use words or predefined prefixes. .PARAMETER Suffix Sets or updates the suffix for the group naming policy. One can use words or predefined suffixes. .PARAMETER RemoveNamingConvention Removes the prefix and suffix from the group naming policy. .EXAMPLE Set-O365AzureGroupNamingPolicy -Verbose -Prefix 'O365' -Suffix 'Uops', [Company], 'test' -WhatIf .EXAMPLE Set-O365AzureGroupNamingPolicy -Verbose -Prefix 'O365' -Suffix '' -WhatIf .EXAMPLE Set-O365AzureGroupNamingPolicy -Verbose -RemoveNamingConvention -WhatIf .NOTES https://portal.azure.com/#blade/Microsoft_AAD_IAM/GroupsManagementMenuBlade/NamingPolicy #> [cmdletbinding(SupportsShouldProcess, DefaultParameterSetName = 'PrefixSuffix')] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [Parameter(ParameterSetName = 'PrefixSuffix')][string[]] $Prefix, [Parameter(ParameterSetName = 'PrefixSuffix')][string[]] $Suffix, [Parameter(ParameterSetName = 'Remove')][switch] $RemoveNamingConvention ) $CurrentSettings = Get-O365AzureGroupNamingPolicy -NoTranslation -Headers $Headers if ($CurrentSettings.id) { $Uri = "https://graph.microsoft.com/beta/settings/$($CurrentSettings.id)" [Array] $Values = foreach ($Policy in $CurrentSettings.values) { if ($Policy.Name -eq 'PrefixSuffixNamingRequirement') { if ($RemoveNamingConvention) { $ExpectedPolicy = '' } else { $ExpectedPolicy = ($Prefix -join "") + "[GroupName]" + ($Suffix -join "") } [PSCustomObject] @{ name = 'PrefixSuffixNamingRequirement' value = $ExpectedPolicy } } else { $Policy } } $Body = @{ values = $Values } $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method PATCH -Body $Body $Output } } $Script:ScriptBlockNamingPolicy = { param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters) $Static = @( '[Department]' '[Company]' '[Office]' '[StateOrProvince]' '[CountryOrRegion]' '[Title]' ) $Static | Where-Object { $_ -like "*$wordToComplete*" } } Register-ArgumentCompleter -CommandName Set-O365AzureGroupNamingPolicy -ParameterName Prefix -ScriptBlock $Script:ScriptBlockNamingPolicy Register-ArgumentCompleter -CommandName Set-O365AzureGroupNamingPolicy -ParameterName Suffix -ScriptBlock $Script:ScriptBlockNamingPolicy function Set-O365AzureGroupSecurity { <# .SYNOPSIS Set settings for Security Groups "Users can create security groups in Azure portals, API or PowerShell" .DESCRIPTION Set settings for Security Groups "Users can create security groups in Azure portals, API or PowerShell" .PARAMETER Headers Authorization header as created by Connect-O365Admin. If not provided the function will try to fetch it from the current execution context. .PARAMETER AllowedToCreateSecurityGroups Enables or Disables - "Users can create security groups in Azure portals, API or PowerShell" .EXAMPLE Set-O365AzureGroupSecurity -Verbose -AllowedToCreateSecurityGroups $true -WhatIf .NOTES https://portal.azure.com/#blade/Microsoft_AAD_IAM/GroupsManagementMenuBlade/General #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [parameter(Mandatory)][bool] $AllowedToCreateSecurityGroups ) # "https://graph.microsoft.com/beta/policies/authorizationPolicy/authorizationPolicy" $Uri = "https://graph.microsoft.com/v1.0/policies/authorizationPolicy" $Body = @{ defaultUserRolePermissions = @{ allowedToCreateSecurityGroups = $AllowedToCreateSecurityGroups } } $null = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method PATCH -Body $Body } function Set-O365AzureGroupSelfService { <# .SYNOPSIS Set settings for Self Service Group Management - "Owners can manage group membership requests in the Access Panel" .DESCRIPTION Set settings for Self Service Group Management - "Owners can manage group membership requests in the Access Panel" .PARAMETER Headers Authorization header as created by Connect-O365Admin. If not provided the function will try to fetch it from the current execution context. .PARAMETER OwnersCanManageGroupMembershipRequests Enables or disable Self Service Group Management - "Owners can manage group membership requests in the Access Panel" .PARAMETER RestrictUserAbilityToAccessGroupsFeatures Enables or disables Self Service Group Management - "Restrict user ability to access groups features in the Access Panel. Group and User Admin will have read-only access when the value of this setting is 'Yes'." .EXAMPLE Set-O365AzureGroupSelfService -Verbose -OwnersCanManageGroupMembershipRequests $true -WhatIf .NOTES https://portal.azure.com/#blade/Microsoft_AAD_IAM/GroupsManagementMenuBlade/General #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [parameter()][bool] $OwnersCanManageGroupMembershipRequests, [parameter()][bool] $RestrictUserAbilityToAccessGroupsFeatures ) $Uri = "https://main.iam.ad.ext.azure.com/api/Directories/SsgmProperties/" $Body = @{} if ($PSBoundParameters.ContainsKey("OwnersCanManageGroupMembershipRequests")) { $Body['userDelegationEnabled'] = $OwnersCanManageGroupMembershipRequests # It seems that to enable selfServiceGroupManagement one needs to enable userDelegationEnabled which cannot be read # from the same URL as the other properties, but selfServiceGroupManagement seems to be the value we need #$Body['selfServiceGroupManagementEnabled'] = $OwnersCanManageGroupMembershipRequests } if ($PSBoundParameters.ContainsKey("RestrictUserAbilityToAccessGroupsFeatures")) { $Body['groupsInAccessPanelEnabled'] = -not $RestrictUserAbilityToAccessGroupsFeatures } $null = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method PUT -Body $Body } function Set-O365AzureMultiFactorAuthentication { <# .SYNOPSIS Configures Multi-Factor Authentication (MFA) settings for an Office 365 tenant. .DESCRIPTION This function allows administrators to modify various settings related to Multi-Factor Authentication (MFA) for their Office 365 tenant. It includes options such as account lockout policies, fraud alert configurations, and bypass settings. .PARAMETER Headers Specifies the headers for the API request, typically including authorization details. .PARAMETER AccountLockoutDurationMinutes Specifies the duration in minutes that an account remains locked after reaching the threshold of failed MFA attempts. .PARAMETER AccountLockoutResetMinutes Defines the time period in minutes after which the count of failed MFA attempts is reset. .PARAMETER AccountLockoutThreshold Number of MFA denials to trigger account lockout .PARAMETER AllowPhoneMenu Parameter description .PARAMETER BlockForFraud Automatically block users who report fraud .PARAMETER CallerId MFA caller ID number (US phone number only) .PARAMETER DefaultBypassTimespan Default one-time bypass seconds .PARAMETER EnableFraudAlert Allow users to submit fraud alerts .PARAMETER FraudCode Code to report fraud during initial greeting .PARAMETER FraudNotificationEmailAddresses Recipient's Email Address .PARAMETER OneTimeBypassEmailAddresses Recipient's One-Time Email Addresses for Bypass .PARAMETER PinAttempts Number of PIN attempts allowed per call .PARAMETER SayExtensionDigits Parameter description .PARAMETER SmsTimeoutSeconds Two-way text message timeout seconds .PARAMETER Caches Parameter description .PARAMETER Notifications Parameter description .PARAMETER NotificationEmailAddresses Parameter description .PARAMETER Greetings Parameter description .PARAMETER BlockedUsers Parameter description .PARAMETER BypassedUsers Parameter description .EXAMPLE An example .NOTES Based on: https://portal.azure.com/#blade/Microsoft_AAD_IAM/MultifactorAuthenticationMenuBlade/GettingStarted/fromProviders/ #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [nullable[int]] $AccountLockoutDurationMinutes, [nullable[int]] $AccountLockoutCounterResetMinutes, [nullable[int]] $AccountLockoutDenialsToTriggerLockout, #$AllowPhoneMenu, [nullable[bool]] $BlockForFraud, #$CallerId, #$DefaultBypassTimespan, [nullable[bool]] $EnableFraudAlert, [nullable[int]] $FraudCode #$FraudNotificationEmailAddresses, #$OneTimeBypassEmailAddresses, #$PinAttempts, #$SayExtensionDigits, #$SmsTimeoutSeconds, #$Caches, #$Notifications, #$NotificationEmailAddresses #$Greetings , #$BlockedUsers , #$BypassedUsers ) #$Uri = "https://main.iam.ad.ext.azure.com/api/MultiFactorAuthentication/GetOrCreateExpandedTenantModel?tenantName=Evotec" # $Uri = "https://main.iam.ad.ext.azure.com/api/MultiFactorAuthentication/GetOrCreateExpandedTenantModel" # Whatever I do, doesn't work! $Uri = "https://main.iam.ad.ext.azure.com/api/MultiFactorAuthentication/TenantModel?licenseKey=" $Body = [ordered] @{} <# #tenantId = $CurrentSettings #: ceb371f6 #licenseKey = $CurrentSettings #: #customerId = $CurrentSettings #: AllowPhoneMenu = $allowPhoneMenu #: False BlockForFraud = $BlockForFraud #: False CallerId = $callerId #: 8553308653 DefaultBypassTimespan = $defaultBypassTimespan #: 300 EnableFraudAlert = $EnableFraudAlert #: True FraudCode = $fraudCode #: 0 FraudNotificationEmailAddresses = $fraudNotificationEmailAddresses #: OneTimeBypassEmailAddresses = $oneTimeBypassEmailAddresses #: PinAttempts = $pinAttempts #: SayExtensionDigits = $sayExtensionDigits #: False SmsTimeoutSeconds = $smsTimeoutSeconds #: 60 #caches = $caches #: {} Notifications = $notifications #: NotificationEmailAddresses = $notificationEmailAddresses #: {} #greetings = $greetings #: {} #blockedUsers = $blockedUsers #: {} #bypassedUsers = $bypassedUsers #: {} #groups = $groups #etag = $etag #> if ($PSBoundParameters.ContainsKey('AccountLockoutDurationMinutes')) { $Body['AccountLockoutDurationMinutes'] = $AccountLockoutDurationMinutes } if ($PSBoundParameters.ContainsKey('AccountLockoutCounterResetMinutes')) { $Body['AccountLockoutResetMinutes'] = $AccountLockoutCounterResetMinutes } if ($PSBoundParameters.ContainsKey('AccountLockoutDenialsToTriggerLockout')) { $Body['AccountLockoutThreshold'] = $AccountLockoutDenialsToTriggerLockout } if ($PSBoundParameters.ContainsKey('BlockForFraud')) { $Body['BlockForFraud'] = $BlockForFraud } if ($PSBoundParameters.ContainsKey('EnableFraudAlert')) { $Body['EnableFraudAlert'] = $EnableFraudAlert } if ($PSBoundParameters.ContainsKey('FraudCode')) { $Body['FraudCode'] = $FraudCode } $null = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method PATCH -Body $Body } function Set-O365AzureProperties { <# .SYNOPSIS Changes the properties of Azure Active Directory (Azure AD) for the current tenant. .DESCRIPTION Changes the properties of Azure Active Directory (Azure AD) for the current tenant - available at URL: https://aad.portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/Properties .PARAMETER Headers Authorization header as created by Connect-O365Admin. If not provided the function will try to fetch it from the current execution context. .PARAMETER DisplayName Name of the tenant .PARAMETER TechnicalContact Technical contact for the tenant .PARAMETER GlobalPrivacyContact Global privacy contact for the tenant .PARAMETER PrivacyStatementURL Privacy statement URL for the tenant .EXAMPLE Set-O365AzureProperties -Verbose -Name "Evotec Test" -TechnicalContact 'test@evotec.pl' -GlobalPrivacyContact 'test@evotec.pl' -PrivacyStatementURL "https://test.pl" -WhatIf .EXAMPLE Set-O365AzureProperties -Verbose -Name "Evotec" -TechnicalContact 'test@evotec.pl' -GlobalPrivacyContact $null -PrivacyStatementURL $null -WhatIf .NOTES Please note that Technical Contact cannot be removed. It always needs to be set. #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [alias('Name')][string] $DisplayName, [string] $TechnicalContact, [string] $GlobalPrivacyContact, [string] $PrivacyStatementURL ) $Uri = "https://main.iam.ad.ext.azure.com/api/Directories" $CurrentSettings = Get-O365AzureProperties -Headers $Headers -NoTranslation if ($CurrentSettings) { $Body = @{ objectId = $CurrentSettings.objectId # displayName = $CurrentSettings.displayName # companyLastDirSyncTime = $CurrentSettings.companyLastDirSyncTime # dirSyncEnabled = $CurrentSettings.dirSyncEnabled # replicationScope = $CurrentSettings.replicationScope # dataCenterLocation = $CurrentSettings.dataCenterLocation # countryLetterCode = $CurrentSettings.countryLetterCode # countryName = $CurrentSettings.countryName # preferredLanguage = $CurrentSettings.preferredLanguage # preferredLanguages = $CurrentSettings.preferredLanguages # verifiedDomains = $CurrentSettings.verifiedDomains # globalAdminCanManageAzureSubscriptions = $CurrentSettings.globalAdminCanManageAzureSubscriptions# privacyProfile = $CurrentSettings.privacyProfile # technicalNotificationMails = $CurrentSettings.technicalNotificationMails # } $Setting = $false if ($PSBoundParameters.ContainsKey('DisplayName')) { $Body.displayName = $DisplayName $Setting = $true } if ($PSBoundParameters.ContainsKey('TechnicalContact')) { if ($TechnicalContact) { $Body.technicalNotificationMails = @( $TechnicalContact ) } else { Write-Warning -Message "Set-O365AzureProperties - Using empty/null Technical Contact is not supported." return $Body.technicalNotificationMails = '' } $Setting = $true } if ($PSBoundParameters.ContainsKey('GlobalPrivacyContact')) { $Body.privacyProfile.contactEmail = $GlobalPrivacyContact $Setting = $true } if ($PSBoundParameters.ContainsKey('PrivacyStatementURL')) { $Body.privacyProfile.statementUrl = $PrivacyStatementURL $Setting = $true } if ($Setting) { $null = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method PUT -Body $Body } else { Write-Warning -Message "Set-O365AzureProperties - No settings to update" } } } <# $session = New-Object Microsoft.PowerShell.Commands.WebRequestSession $session.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36 Edg/94.0.992.38" Invoke-WebRequest -UseBasicParsing -Uri "https://main.iam.ad.ext.azure.com/api/Directories" ` -Method "PUT" ` -WebSession $session ` -Headers @{ "x-ms-client-session-id" = "2c99a939029b4409ac6028764b17bb03" "Accept-Language" = "en" "Authorization" = "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Imwzc1EtNTBjQ0g0eEJWWkxIVEd3blNSNzY4MCIsImtpZCI6Imwzc1EtNTBjQ0g0eEJWWkxIVEd3blNSNzY4MCJ9.eyJhdWQiOiI3NDY1ODEzNi0xNGVjLTQ2MzAtYWQ5Yi0yNmUxNjBmZjBmYzYiLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC84YTg1MjYxMi1lZjc5LTQzNDEtOTdkNy1hMTliMmZhNjRjY2UvIiwiaWF0IjoxNjMzOTYzMDE2LCJuYmYiOjE2MzM5NjMwMTYsImV4cCI6MTYzMzk2NjkxNiwiYWNyIjoiMSIsImFpbyI6IkFWUUFxLzhUQUFBQW5xenkxTURoekJveEhscXVWb3pCRzB4MWsranppc3ZxZ05uOFdYTkk2eXYwYitpMWVja2tNWlJFaDYrMW1KYktSazR6azBxcDBZSjArSnZLK3FuakNQSW9YVHg3SHFERVltcU5LVTNCMDZzPSIsImFtciI6WyJwd2QiLCJtZmEiXSwiYXBwaWQiOiJjNDRiNDA4My0zYmIwLTQ5YzEtYjQ3ZC05NzRlNTNjYmRmM2MiLCJhcHBpZGFjciI6IjIiLCJmYW1pbHlfbmFtZSI6IktseXMiLCJnaXZlbl9uYW1lIjoiUHJ6ZW15c2xhdyIsImlwYWRkciI6Ijg5Ljc3LjEwMi4xNyIsIm5hbWUiOiJQcnplbXlzbGF3IEtseXMgQ0FETSIsIm9pZCI6ImM5NTY5ODhmLTZlZjMtNDEwZi1hNjQyLWVlMTM0ZWY3MjdjMyIsInB1aWQiOiIxMDAzMjAwMTIwNTc0MjdCIiwicmgiOiIwLkFWOEFFaWFGaW5udlFVT1gxNkdiTDZaTXpvTkFTOFN3TzhGSnRIMlhUbFBMM3p4ZkFBUS4iLCJzY3AiOiJ1c2VyX2ltcGVyc29uYXRpb24iLCJzdWIiOiJleUNWMDRhd1dqS0VHMnNUc0dxSmtHSjlZUWJCRzNYazFKcTBpam1CTkc4IiwidGVuYW50X3JlZ2lvbl9zY29wZSI6IkVVIiwidGlkIjoiOGE4NTI2MTItZWY3OS00MzQxLTk3ZDctYTE5YjJmYTY0Y2NlIiwidW5pcXVlX25hbWUiOiJDQURNX0paNVFAZXVyb2ZpbnN0ZXN0My5vbm1pY3Jvc29mdC5jb20iLCJ1cG4iOiJDQURNX0paNVFAZXVyb2ZpbnN0ZXN0My5vbm1pY3Jvc29mdC5jb20iLCJ1dGkiOiJaeEtwdlVRRGVrcWpFV1FucEZVcEFRIiwidmVyIjoiMS4wIiwid2lkcyI6WyI2MmU5MDM5NC02OWY1LTQyMzctOTE5MC0wMTIxNzcxNDVlMTAiLCJiNzlmYmY0ZC0zZWY5LTQ2ODktODE0My03NmIxOTRlODU1MDkiXSwieG1zX3RjZHQiOjE1ODYyNzExNDF9.W0pZUmLN4Xj-o-dWSfJKF1HG08wxvuQEM-mW88EnSKAIVSI6IWAOsWAUWDMdDwuy9DzjjB9u3F_V9ahFWid0t-mn5i0jzswEeg5BanDJOs3sz4KZeKYzXe4Q5eastFKvw526ATAhoQD-lCZ00w7S82vBOB_f5jol_mtMCWopANu5OonTX9glcz2mHxj1_vjNM5NZeOYqCc5Lss8d2XV5ghqauW-mLcLd3hVI6eX_RBKpTm7Y2vgc4EyAte35iGUgPveeFAmF8DyWm1V9BAFqD7lo2dopgXxt3rWXUCw4Zixt6u3fDxpUoIEoAvsInGK-Q8rFbosNyk78Bg6Ja7EzQg" "x-ms-effective-locale" = "en.en-us" "Accept" = "*/*" "Referer" = "" "x-ms-client-request-id" = "c465c06e-6937-40ba-88aa-ba63dc35c01e" } ` -ContentType "application/json" ` -Body ([System.Text.Encoding]::UTF8.GetBytes(" {`"objectId`":`"8a852612-ef79-4341-97d7-a19b2fa64cce`", `"displayName`":`"Eurofins GSC France`", `"companyLastDirSyncTime`":`"2021-10-11T14:42:59Z`", `"dirSyncEnabled`":true,`"replicationScope`":`"EU`", `"dataCenterLocation`":`"EU Model Clause compliant datacenters`", `"countryLetterCode`":`"FR`", `"countryName`":`"France`",`"preferredLanguage`":`"en`", `"preferredLanguages`":[{`"displayName`":`"English`",`"languageCode`":`"en`"}, {`"displayName`":`"fran$([char]231)ais`",`"languageCode`":`"fr`"}], `"verifiedDomains`":[{`"id`":`"000520000819CC42`",`"type`":`"Managed`",`"name`": `"eurofinstest3.onmicrosoft.com`",`"initial`":true,`"isDirSyncExchangeOnlineDomain`":false}, {`"id`":`"000520000866EC97`",`"type`":`"Managed`",`"name`":`"eurofinstest3.mail.onmicrosoft.com`", `"initial`":false,`"isDirSyncExchangeOnlineDomain`":true},{`"id`":`"000520000A1A4828`",`"type`":`"Managed`", `"name`":`"eurofins-test.com`",`"initial`":false,`"isDirSyncExchangeOnlineDomain`":false}], `"globalAdminCanManageAzureSubscriptions`":false, `"privacyProfile`":{`"contactEmail`":`"`",`"statementUrl`":`"https://eurofins.com`"}, `"technicalNotificationMails`":[`"aurelienlesage@eurofins.com`"]}")) #> function Set-O365AzurePropertiesSecurity { <# .SYNOPSIS Enables or disables Security Defaults for Azure AD. .DESCRIPTION This function updates the Security Defaults setting for Azure AD based on the provided parameter. Security Defaults is a set of security settings that are enabled by default to help protect your organization. If Classic policies are enabled, Security Defaults cannot be enabled. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .PARAMETER EnableSecurityDefaults Specifies whether to enable or disable Security Defaults. This parameter is mandatory. .EXAMPLE Set-O365AzurePropertiesSecurity -Headers $headers -EnableSecurityDefaults $true .NOTES For more information on Security Defaults, visit: https://docs.microsoft.com/en-us/azure/active-directory/fundamentals/concept-fundamentals-security-defaults #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [parameter(Mandatory)][bool] $EnableSecurityDefaults ) $Uri = "https://main.iam.ad.ext.azure.com/api/SecurityDefaults/UpdateSecurityDefaultOnSave?enableSecurityDefaults=$EnableSecurityDefaults" $CurrentSettings = Get-O365AzurePropertiesSecurity -Headers $Headers if ($CurrentSettings.anyClassicPolicyEnabled -eq $false) { $null = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method PUT } elseif ($CurrentSettings.anyClassicPolicyEnabled -eq $true) { Write-Warning -Message "Set-O365AzurePropertiesSecurity - It looks like you have Classic policies enabled. Enabling Classic policies prevents you from enabling Security defaults." } } function Set-O365AzureUserSettings { <# .SYNOPSIS Configures user settings for Azure AD. .DESCRIPTION This function allows you to set various user settings for Azure AD. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .PARAMETER UsersCanRegisterApps Specifies whether users can register apps. .PARAMETER RestrictNonAdminUsers Specifies whether to restrict non-admin users. .PARAMETER LinkedInAccountConnection Specifies whether to enable LinkedIn account connection. .PARAMETER LinkedInSelectedGroupObjectId The object ID of the selected LinkedIn group. .PARAMETER LinkedInSelectedGroupDisplayName The display name of the selected LinkedIn group. .EXAMPLE Set-O365UserSettings -RestrictNonAdminUsers $true -LinkedInAccountConnection $true -LinkedInSelectedGroupObjectId 'b6cdb9c3-d660-4558-bcfd-82c14a986b56' .EXAMPLE Set-O365UserSettings -RestrictNonAdminUsers $true -LinkedInAccountConnection $true -LinkedInSelectedGroupDisplayName 'All Users' .EXAMPLE Set-O365UserSettings -RestrictNonAdminUsers $true -LinkedInAccountConnection $false .EXAMPLE Set-O365UserSettings -RestrictNonAdminUsers $true .NOTES For more information, visit: https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/UserSettings #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [nullable[bool]] $UsersCanRegisterApps, [nullable[bool]] $RestrictNonAdminUsers, [nullable[bool]] $LinkedInAccountConnection, [string] $LinkedInSelectedGroupObjectId, [string] $LinkedInSelectedGroupDisplayName ) $Uri = "https://main.iam.ad.ext.azure.com/api/Directories/PropertiesV2" $Body = @{ usersCanRegisterApps = $UsersCanRegisterApps restrictNonAdminUsers = $RestrictNonAdminUsers } Remove-EmptyValue -Hashtable $Body if ($null -ne $LinkedInAccountConnection) { if ($LinkedInAccountConnection -eq $true -and $linkedInSelectedGroupObjectId) { $Body.enableLinkedInAppFamily = 4 $Body.linkedInSelectedGroupObjectId = $linkedInSelectedGroupObjectId } elseif ($LinkedInAccountConnection -eq $true -and $LinkedInSelectedGroupDisplayName) { $Body.enableLinkedInAppFamily = 4 $Body.linkedInSelectedGroupDisplayName = $LinkedInSelectedGroupDisplayName } elseif ($LinkedInAccountConnection -eq $true) { $Body.enableLinkedInAppFamily = 0 $Body.linkedInSelectedGroupObjectId = $null } elseif ($LinkedInAccountConnection -eq $false) { $Body.enableLinkedInAppFamily = 1 $Body.linkedInSelectedGroupObjectId = $null } } if ($Body.Keys.Count -gt 0) { $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method PUT -Body $Body # $Output } } function Set-O365BillingLicenseAutoClaim { <# .SYNOPSIS Sets the auto-claim policy for Office 365 licenses. .DESCRIPTION This function enables or disables the auto-claim policy for Office 365 licenses. The auto-claim policy allows users to automatically claim available licenses without administrative intervention. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .PARAMETER EnableAutoClaim Specifies whether to enable or disable the auto-claim policy. This parameter is optional. .EXAMPLE Set-O365BillingLicenseAutoClaim -Headers $headers -EnableAutoClaim $true .NOTES For more information on managing Office 365 licenses, visit: https://admin.microsoft.com/#/Billing #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [bool] $EnableAutoClaim ) $Uri = "https://admin.microsoft.com/fd/m365licensing/v1/policies/autoclaim" if ($PSBoundParameters.ContainsKey("EnableAutoClaim")) { $Body = [ordered] @{ policyValue = if ($EnableAutoClaim -eq $true) { "Enabled" } else { "Disabled" } } $null = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body } } function Set-O365BillingNotifications { <# .SYNOPSIS Sets settings for Billing notifications, allowing control over Invoice PDF delivery. .DESCRIPTION This function configures the settings for Billing notifications, enabling the user to specify whether to receive Invoice PDFs. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .PARAMETER SendInvoiceEmails Specifies whether to send Invoice emails. This parameter is mandatory. .EXAMPLE Set-O365BillingNotifications -Headers $headers -SendInvoiceEmails $true .NOTES For more information on Billing notifications settings, visit: https://admin.microsoft.com/#/BillingNotifications #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [parameter(Mandatory)][bool] $SendInvoiceEmails ) $Uri = "https://admin.microsoft.com/fd/commerceMgmt/mgmtsettings/invoicePreference?api-version=1.0" $Body = @{ sendInvoiceEmails = $SendInvoiceEmails } $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body if ($Output.setInvoicePreferenceSuccessful -eq $true) { } } function Set-O365GroupLicenses { <# .SYNOPSIS Sets Office 365 group licenses based on provided parameters. .DESCRIPTION This function assigns or removes licenses for an Office 365 group based on the provided parameters. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .PARAMETER GroupID The ID of the Office 365 group to assign licenses to. .PARAMETER GroupDisplayName The display name of the Office 365 group to assign licenses to. .PARAMETER Licenses An array of licenses to assign to the group. .EXAMPLE Set-O365GroupLicenses -Headers $headers -GroupID "12345" -Licenses @($License1, $License2) .NOTES For more information, visit: https://docs.microsoft.com/en-us/office365/enterprise/office-365-service-descriptions #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [parameter()][string] $GroupID, [parameter()][alias('GroupName')][string] $GroupDisplayName, [Array] $Licenses ) $Uri = "https://main.iam.ad.ext.azure.com/api/AccountSkus/assignUpdateRemove" if ($GroupID) { $Group = $GroupID #$GroupSearch = Get-O365Group -Id $GroupID #if ($GroupSearch.id) { # $GroupName = $GroupSearch.displayName #} } elseif ($GroupDisplayName) { $GroupSearch = Get-O365Group -DisplayName $GroupDisplayName if ($GroupSearch.id) { $Group = $GroupSearch.id #$GroupName = $GroupSearch.displayName } } if ($Group) { $CurrentLicenses = Get-O365GroupLicenses -GroupID $Group -NoTranslation if ($CurrentLicenses.objectid) { # we cache it for better use of search $CacheLicenses = [ordered] @{} foreach ($License in $CurrentLicenses.licenses) { $CacheLicenses[$License.accountSkuId] = $License } <# accountSkuId disabledServicePlans hasErrors errorCount ------------ -------------------- --------- ---------- evotecpoland:FLOW_FREE {} 0 evotecpoland:POWER_BI_STANDARD {} 0 evotecpoland:POWER_BI_PRO {} 0 evotecpoland:ENTERPRISEPACK {POWER_VIRTUAL_AGENTS_O365_P2, PROJECT_O365_P2} 0 #> $AddLicenses = [System.Collections.Generic.List[System.Collections.IDictionary]]::new() $RemoveLicenses = [System.Collections.Generic.List[string]]::new() $UpdateLicenses = [System.Collections.Generic.List[System.Collections.IDictionary]]::new() foreach ($License in $Licenses) { if ($CacheLicenses[$License.accountSkuId]) { if (-not (Compare-Object -ReferenceObject $License.disabledServicePlans -DifferenceObject $CacheLicenses[$License.accountSkuId].disabledServicePlans)) { # We do nothing, because the licenses have the same disabled service plans are the same } else { $UpdateLicenses.Add($License) } } else { $AddLicenses.Add($License) } } foreach ($License in $CurrentLicenses.licenses) { if ($License.accountSkuId -notin $Licenses.accountSkuId) { #$PrepareForRemoval = New-O365License -DisabledServicesName $License.disabledServicePlans -LicenseSKUID $License.accountSkuId #if ($PrepareForRemoval) { $RemoveLicenses.Add($License.accountSkuId) #} } } $Body = [ordered] @{ assignments = @( [ordered] @{ objectId = $Group #displayName = $GroupName isUser = $false addLicenses = $AddLicenses removeLicenses = $RemoveLicenses updateLicenses = $UpdateLicenses } ) } $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body $Output } else { Write-Warning -Message "Set-O365GroupLicenses - Querying for current group licenses failed. Skipping." } } else { Write-Error -Message "Set-O365GroupLicenses - Couldn't find group. Skipping." } } function Set-O365OrgAccountLinking { <# .SYNOPSIS Users who connect their Azure AD account with their MSA account can earn rewards points when they search on Bing. This cmdlet allows to enable/disable this feature. .DESCRIPTION Users who connect their Azure AD account with their MSA account can earn rewards points when they search on Bing. This cmdlet allows to enable/disable this feature. .PARAMETER Headers The headers to use for the request .PARAMETER EnableExtension Enable or disable the feature .EXAMPLE Set-O365OrgAccountLinking .NOTES General notes #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [Parameter(Mandatory)][bool] $EnableExtension ) $Uri = "https://admin.microsoft.com/fd/bfb/api/v3/office/switch/feature" if ($EnableExtension -eq $false) { $Body = @{ features = @('AccountLinking') } $null = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method DELETE -Body $Body } elseif ($EnableExtension -eq $true) { $Body = @{ features = @('AccountLinking') } $null = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method PUT -Body $Body } } function Set-O365OrgAdoptionScore { <# .SYNOPSIS Configures the organization's adoption score settings for Office 365. .DESCRIPTION This function allows setting various configurations related to the organization's adoption score in Office 365. It enables or disables insights, sets group-level insights, and allows approved admins to send recommendations. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .PARAMETER EnableInsights Specifies whether to enable insights for the organization. .PARAMETER LimitGroupId An array of group IDs to limit the insights for. .PARAMETER LimitGroupName An array of group names to limit the insights for. .PARAMETER TurnOnGroupLevelInsights Enables or disables group-level insights. .PARAMETER AllowApprovedAdminsToSendRecommendations Specifies whether approved admins are allowed to send recommendations. .EXAMPLE Set-O365OrgAdoptionScore -Headers $headers -EnableInsights $true -TurnOnGroupLevelInsights $true -AllowApprovedAdminsToSendRecommendations $true .NOTES This function is used to manage the organization's adoption score settings, including enabling insights, setting group-level insights, and allowing approved admins to send recommendations. #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [Parameter(Mandatory)][bool] $EnableInsights, [Array] $LimitGroupId, [Array] $LimitGroupName, [Parameter(Mandatory)][bool] $TurnOnGroupLevelInsights, [Parameter(Mandatory)][bool] $AllowApprovedAdminsToSendRecommendations ) $Uri = "https://admin.microsoft.com/admin/api/reports/productivityScoreCustomerOption" $Body = @{ ProductivityScoreOptedIn = $EnableInsights PSGroupsOptedOut = $false CohortInsightOptedIn = $false ActionFlowOptedIn = $false PSOptedOutGroupIds = $null } if ($PSBoundParameters.ContainsKey('CohortInsightOptedIn')) { $Body['CohortInsightOptedIn'] = $TurnOnGroupLevelInsights } if ($PSBoundParameters.ContainsKey('AllowApprovedAdminsToSendRecommendations')) { $Body['ActionFlowOptedIn'] = $AllowApprovedAdminsToSendRecommendations } if ($LimitGroupId.Count -gt 0 -or $LimitGroupName.Count -gt 0) { $Body['PSGroupsOptedOut'] = $true [Array] $Groups = @( foreach ($Group in $LimitGroupID) { $GroupInformation = Get-O365Group -Id $Group -Headers $Headers if ($GroupInformation.id) { $GroupInformation } } foreach ($Group in $LimitGroupName) { $GroupInformation = Get-O365Group -DisplayName $Group -Headers $Headers if ($GroupInformation.id) { $GroupInformation } } ) $Body['PSOptedOutGroupIds'] = @( foreach ($Group in $Groups) { $Group.id } ) } $null = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body } function Set-O365OrgAzureSpeechServices { <# .SYNOPSIS Provides functionality to enable or disable the organization-wide language model for Azure Speech Services. .DESCRIPTION This function allows enabling or disabling the organization-wide language model for Azure Speech Services. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .PARAMETER AllowTheOrganizationWideLanguageModel Specifies whether to enable or disable the organization-wide language model. .EXAMPLE Set-O365OrgAzureSpeechServices -Headers $headers -AllowTheOrganizationWideLanguageModel $true .NOTES For more information, visit: https://admin.microsoft.com/admin/api/services/apps/azurespeechservices #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [bool] $AllowTheOrganizationWideLanguageModel ) $Uri = "https://admin.microsoft.com/admin/api/services/apps/azurespeechservices" $Body = @{ isTenantEnabled = $AllowTheOrganizationWideLanguageModel } $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body $Output } function Set-O365OrgBingDataCollection { <# .SYNOPSIS Provides functionality to set consent for Bing data collection in the organization. .DESCRIPTION This function allows setting consent for Bing data collection in the organization. .PARAMETER Headers A dictionary containing the necessary headers for the API request, typically including authorization information. .PARAMETER IsBingDataCollectionConsented Specifies whether Bing data collection is consented or not. .EXAMPLE Set-O365OrgBingDataCollection -Headers $headers -IsBingDataCollectionConsented $true .NOTES For more information, visit: https://admin.microsoft.com/admin/api/settings/security/bingdatacollection #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [nullable[bool]] $IsBingDataCollectionConsented ) $Uri = "https://admin.microsoft.com/admin/api/settings/security/bingdatacollection" $Body = [ordered] @{ IsBingDataCollectionConsented = $IsBingDataCollectionConsented } $null = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body } function Set-O365OrgBookings { <# .SYNOPSIS Set various settings for the Bookings app in the organization. .DESCRIPTION This function allows setting various configurations for the Bookings app in the organization. .PARAMETER Headers Authentication token and additional information created with Connect-O365Admin. .PARAMETER Enabled Enables or disables the Bookings app. .PARAMETER ShowPaymentsToggle Shows or hides the payments toggle in the Bookings app. .PARAMETER PaymentsEnabled Enables or disables payments in the Bookings app. .PARAMETER ShowSocialSharingToggle Shows or hides the social sharing toggle in the Bookings app. .PARAMETER SocialSharingRestricted Restricts social sharing in the Bookings app. .PARAMETER ShowBookingsAddressEntryRestrictedToggle Shows or hides the address entry restriction toggle in the Bookings app. .PARAMETER BookingsAddressEntryRestricted Restricts address entry in the Bookings app. .PARAMETER ShowBookingsAuthEnabledToggle Shows or hides the authentication enabled toggle in the Bookings app. .PARAMETER BookingsAuthEnabled Enables or disables authentication in the Bookings app. .PARAMETER ShowBookingsCreationOfCustomQuestionsRestrictedToggle Shows or hides the custom questions creation restriction toggle in the Bookings app. .PARAMETER BookingsCreationOfCustomQuestionsRestricted Restricts custom questions creation in the Bookings app. .PARAMETER ShowBookingsExposureOfStaffDetailsRestrictedToggle Shows or hides the staff details exposure restriction toggle in the Bookings app. .PARAMETER BookingsExposureOfStaffDetailsRestricted Restricts staff details exposure in the Bookings app. .PARAMETER ShowBookingsNotesEntryRestrictedToggle Shows or hides the notes entry restriction toggle in the Bookings app. .PARAMETER BookingsNotesEntryRestricted Restricts notes entry in the Bookings app. .PARAMETER ShowBookingsPhoneNumberEntryRestrictedToggle Shows or hides the phone number entry restriction toggle in the Bookings app. .PARAMETER BookingsPhoneNumberEntryRestricted Restricts phone number entry in the Bookings app. .PARAMETER ShowStaffApprovalsToggle Shows or hides the staff approvals toggle in the Bookings app. .PARAMETER StaffMembershipApprovalRequired Requires staff membership approval in the Bookings app. .EXAMPLE Set-O365OrgBookings -Headers $headers -Enabled $true -ShowPaymentsToggle $false -PaymentsEnabled $false .NOTES This function allows granular control over various settings in the Bookings app. #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [nullable[bool]] $Enabled, [nullable[bool]] $ShowPaymentsToggle, [nullable[bool]] $PaymentsEnabled, [nullable[bool]] $ShowSocialSharingToggle, [nullable[bool]] $SocialSharingRestricted, [nullable[bool]] $ShowBookingsAddressEntryRestrictedToggle, [nullable[bool]] $BookingsAddressEntryRestricted, [nullable[bool]] $ShowBookingsAuthEnabledToggle, [nullable[bool]] $BookingsAuthEnabled, [nullable[bool]] $ShowBookingsCreationOfCustomQuestionsRestrictedToggle, [nullable[bool]] $BookingsCreationOfCustomQuestionsRestricted, [nullable[bool]] $ShowBookingsExposureOfStaffDetailsRestrictedToggle, [nullable[bool]] $BookingsExposureOfStaffDetailsRestricted, [nullable[bool]] $ShowBookingsNotesEntryRestrictedToggle, [nullable[bool]] $BookingsNotesEntryRestricted, [nullable[bool]] $ShowBookingsPhoneNumberEntryRestrictedToggle, [nullable[bool]] $BookingsPhoneNumberEntryRestricted, [nullable[bool]] $ShowStaffApprovalsToggle, [nullable[bool]] $StaffMembershipApprovalRequired ) $Uri = "https://admin.microsoft.com/admin/api/settings/apps/bookings" $CurrentSettings = Get-O365OrgBookings -Headers $Headers if ($CurrentSettings) { $Body = @{ Enabled = $CurrentSettings.Enabled #: True ShowPaymentsToggle = $CurrentSettings.ShowPaymentsToggle #: False PaymentsEnabled = $CurrentSettings.PaymentsEnabled #: False ShowSocialSharingToggle = $CurrentSettings.ShowSocialSharingToggle #: True SocialSharingRestricted = $CurrentSettings.SocialSharingRestricted #: False ShowBookingsAddressEntryRestrictedToggle = $CurrentSettings.ShowBookingsAddressEntryRestrictedToggle #: False BookingsAddressEntryRestricted = $CurrentSettings.BookingsAddressEntryRestricted #: False ShowBookingsAuthEnabledToggle = $CurrentSettings.ShowBookingsAuthEnabledToggle #: False BookingsAuthEnabled = $CurrentSettings.BookingsAuthEnabled #: False ShowBookingsCreationOfCustomQuestionsRestrictedToggle = $CurrentSettings.ShowBookingsCreationOfCustomQuestionsRestrictedToggle #: False BookingsCreationOfCustomQuestionsRestricted = $CurrentSettings.BookingsCreationOfCustomQuestionsRestricted #: False ShowBookingsExposureOfStaffDetailsRestrictedToggle = $CurrentSettings.ShowBookingsExposureOfStaffDetailsRestrictedToggle #: False BookingsExposureOfStaffDetailsRestricted = $CurrentSettings.BookingsExposureOfStaffDetailsRestricted #: False ShowBookingsNotesEntryRestrictedToggle = $CurrentSettings.ShowBookingsNotesEntryRestrictedToggle #: False BookingsNotesEntryRestricted = $CurrentSettings.BookingsNotesEntryRestricted #: False ShowBookingsPhoneNumberEntryRestrictedToggle = $CurrentSettings.ShowBookingsPhoneNumberEntryRestrictedToggle #: False BookingsPhoneNumberEntryRestricted = $CurrentSettings.BookingsPhoneNumberEntryRestricted #: False ShowStaffApprovalsToggle = $CurrentSettings.ShowStaffApprovalsToggle #: True StaffMembershipApprovalRequired = $CurrentSettings.StaffMembershipApprovalRequired #: False } if ($null -ne $Enabled) { $Body.Enabled = $Enabled } if ($null -ne $ShowPaymentsToggle) { $Body.ShowPaymentsToggle = $ShowPaymentsToggle } if ($null -ne $PaymentsEnabled) { $Body.PaymentsEnabled = $PaymentsEnabled } if ($null -ne $ShowSocialSharingToggle) { $Body.ShowSocialSharingToggle = $ShowSocialSharingToggle } if ($null -ne $SocialSharingRestricted) { $Body.SocialSharingRestricted = $SocialSharingRestricted } if ($null -ne $ShowBookingsAddressEntryRestrictedToggle) { $Body.ShowBookingsAddressEntryRestrictedToggle = $ShowBookingsAddressEntryRestrictedToggle } if ($null -ne $BookingsAddressEntryRestricted) { $Body.BookingsAddressEntryRestricted = $BookingsAddressEntryRestricted } if ($null -ne $ShowBookingsAuthEnabledToggle) { $Body.ShowBookingsAuthEnabledToggle = $ShowBookingsAuthEnabledToggle } if ($null -ne $BookingsAuthEnabled) { $Body.BookingsAuthEnabled = $BookingsAuthEnabled } if ($null -ne $ShowBookingsCreationOfCustomQuestionsRestrictedToggle) { $Body.ShowBookingsCreationOfCustomQuestionsRestrictedToggle = $ShowBookingsCreationOfCustomQuestionsRestrictedToggle } if ($null -ne $BookingsCreationOfCustomQuestionsRestricted) { $Body.BookingsCreationOfCustomQuestionsRestricted = $BookingsCreationOfCustomQuestionsRestricted } if ($null -ne $ShowBookingsExposureOfStaffDetailsRestrictedToggle) { $Body.ShowBookingsExposureOfStaffDetailsRestrictedToggle = $ShowBookingsExposureOfStaffDetailsRestrictedToggle } if ($null -ne $BookingsExposureOfStaffDetailsRestricted) { $Body.BookingsExposureOfStaffDetailsRestricted = $BookingsExposureOfStaffDetailsRestricted } if ($null -ne $ShowBookingsNotesEntryRestrictedToggle) { $Body.ShowBookingsNotesEntryRestrictedToggle = $ShowBookingsNotesEntryRestrictedToggle } if ($null -ne $BookingsNotesEntryRestricted) { $Body.BookingsNotesEntryRestricted = $BookingsNotesEntryRestricted } if ($null -ne $ShowBookingsPhoneNumberEntryRestrictedToggle) { $Body.ShowBookingsPhoneNumberEntryRestrictedToggle = $ShowBookingsPhoneNumberEntryRestrictedToggle } if ($null -ne $BookingsPhoneNumberEntryRestricted) { $Body.BookingsPhoneNumberEntryRestricted = $BookingsPhoneNumberEntryRestricted } if ($null -ne $ShowStaffApprovalsToggle) { $Body.ShowStaffApprovalsToggle = $ShowStaffApprovalsToggle } if ($null -ne $StaffMembershipApprovalRequired) { $Body.StaffMembershipApprovalRequired = $StaffMembershipApprovalRequired } Remove-EmptyValue -Hashtable $Body $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body $Output } } function Set-O365OrgBriefingEmail { <# .SYNOPSIS Configures the Briefing Email feature for an Office 365 organization. .DESCRIPTION Let people in your organization receive Briefing Email .PARAMETER Headers Specifies the headers for the API request. Typically includes authorization tokens. .PARAMETER SubscribeByDefault Specifies whether people in your organization should be subscribed to receive Briefing Email by default. .EXAMPLE $headers = @{Authorization = "Bearer your_token"} Set-O365OrgBriefingEmail -Headers $headers -SubscribeByDefault $true This example sets the Briefing Email feature to be subscribed by default for the Office 365 organization. .NOTES Users will receive Briefing email by default, but can unsubscribe at any time from their Briefing email or Briefing settings page. Email is only sent to users if their Office 365 language is English or Spanish. #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, #[bool] $MailEnable, [bool] $SubscribeByDefault ) $Uri = "https://admin.microsoft.com/admin/api/services/apps/briefingemail" $Body = @{ value = @{ IsSubscribedByDefault = $SubscribeByDefault } } $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body $Output } function Set-O365OrgCalendarSharing { <# .SYNOPSIS Let your users share their calendars with people outside of your organization who have Office 365 or Exchange .DESCRIPTION Let your users share their calendars with people outside of your organization who have Office 365 or Exchange .PARAMETER Headers Authentication Token along with additional information that is created with Connect-O365Admin. If heaaders are not provided it will use the default token. .PARAMETER EnableAnonymousCalendarSharing Enables or Disables anonymous calendar sharing .PARAMETER EnableCalendarSharing Enables or Disables calendar sharing .PARAMETER SharingOption Decide on how to share the calendar - Show calendar free/busy information with time only (CalendarSharingFreeBusySimple) - Show calendar free/busy information with time, subject and location (CalendarSharingFreeBusyDetail) - Show all calendar appointment information (CalendarSharingFreeBusyReviewer) .EXAMPLE Set-O365CalendarSharing -EnableCalendarSharing $false .NOTES General notes #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [nullable[bool]] $EnableAnonymousCalendarSharing, [nullable[bool]] $EnableCalendarSharing, [string][ValidateSet('CalendarSharingFreeBusyDetail', 'CalendarSharingFreeBusySimple', 'CalendarSharingFreeBusyReviewer')] $SharingOption ) # We need to get current settings because it always requires all parameters # If we would just provide one parameter it would reset everything else $CurrentSettings = Get-O365OrgCalendarSharing -Headers $Headers $Body = [ordered] @{ ContractIdentity = $CurrentSettings.ContractIdentity EnableAnonymousCalendarSharing = $CurrentSettings.EnableAnonymousCalendarSharing EnableCalendarSharing = $CurrentSettings.EnableCalendarSharing SharingOption = $CurrentSettings.SharingOption } if ($null -ne $EnableAnonymousCalendarSharing) { $Body.EnableAnonymousCalendarSharing = $EnableAnonymousCalendarSharing } if ($null -ne $EnableCalendarSharing) { $Body.EnableCalendarSharing = $EnableCalendarSharing } if ($SharingOption) { $Body.SharingOption = $SharingOption } $Uri = "https://admin.microsoft.com/admin/api/settings/apps/calendarsharing" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body $Output } function Set-O365OrgCommunicationToUsers { <# .SYNOPSIS Configures the communication settings for end users in an Office 365 organization. .DESCRIPTION This function allows you to enable or disable communication services for end users in your Office 365 organization. It sends a POST request to the Office 365 admin API with the specified settings. .PARAMETER Headers Specifies the headers for the API request. Typically includes authorization tokens. .PARAMETER ServiceEnabled Specifies whether the communication service should be enabled for end users. .EXAMPLE $headers = @{Authorization = "Bearer your_token"} Set-O365OrgCommunicationToUsers -Headers $headers -ServiceEnabled $true This example enables the communication service for end users in the Office 365 organization. .NOTES This function sends a POST request to the Office 365 admin API with the specified settings. #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [Parameter(Mandatory)][bool] $ServiceEnabled ) $Uri = "https://admin.microsoft.com/admin/api/settings/apps/EndUserCommunications" $Body = @{ ServiceEnabled = $ServiceEnabled } $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body #-WhatIf:$WhatIfPreference.IsPresent $Output } function Set-O365OrgCortana { <# .SYNOPSIS Configures the Cortana settings for an Office 365 organization. .DESCRIPTION This function allows you to enable or disable the Cortana service for your Office 365 organization. It sends a POST request to the Office 365 admin API with the specified settings. .PARAMETER Headers Specifies the headers for the API request. Typically includes authorization tokens. .PARAMETER Enabled Specifies whether the Cortana service should be enabled. .EXAMPLE $headers = @{Authorization = "Bearer your_token"} Set-O365OrgCortana -Headers $headers -Enabled $true This example enables the Cortana service for the Office 365 organization. .NOTES This function sends a POST request to the Office 365 admin API with the specified settings. #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [Parameter(Mandatory)][bool] $Enabled ) $Uri = "https://admin.microsoft.com/admin/api/services/apps/cortana" $Body = @{ Enabled = $Enabled } $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body $Output } function Set-O365OrgCustomerLockbox { <# .SYNOPSIS Configures the Customer Lockbox settings for an Office 365 organization. .DESCRIPTION This function allows you to enable or disable the Customer Lockbox feature for your Office 365 organization. It sends a POST request to the Office 365 admin API with the specified settings. .PARAMETER Headers Specifies the headers for the API request. Typically includes authorization tokens. .PARAMETER RequireApproval Specifies whether Customer Lockbox should require approval. .EXAMPLE $headers = @{Authorization = "Bearer your_token"} Set-O365OrgCustomerLockbox -Headers $headers -RequireApproval $true This example enables the Customer Lockbox feature for the Office 365 organization. .NOTES This function sends a POST request to the Office 365 admin API with the specified settings. #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [Parameter(Mandatory)][bool] $RequireApproval ) $Uri = "https://admin.microsoft.com/admin/api/settings/security/dataaccess" $Body = @{ RequireApproval = $RequireApproval } $null = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body } function Set-O365OrgDynamics365ConnectionGraph { <# .SYNOPSIS Configures the Dynamics 365 Connection Graph settings for an Office 365 organization. .DESCRIPTION This function allows you to enable or disable the Dynamics 365 Connection Graph service for your Office 365 organization. It sends a POST request to the Office 365 admin API with the specified settings. .PARAMETER Headers Specifies the headers for the API request. Typically includes authorization tokens. .PARAMETER ServiceEnabled Specifies whether the Dynamics 365 Connection Graph service should be enabled. .PARAMETER ConnectionGraphUsersExclusionGroup Specifies the group of users to be excluded from the Connection Graph. .EXAMPLE $headers = @{Authorization = "Bearer your_token"} Set-O365OrgDynamics365ConnectionGraph -Headers $headers -ServiceEnabled $true -ConnectionGraphUsersExclusionGroup "GroupID" This example enables the Dynamics 365 Connection Graph service for the Office 365 organization and excludes the specified group of users. .NOTES This function sends a POST request to the Office 365 admin API with the specified settings. #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [Parameter(Mandatory)][bool] $ServiceEnabled, [string] $ConnectionGraphUsersExclusionGroup ) $Uri = "https://admin.microsoft.com/admin/api/settings/apps/dcg" $Body = @{ ServiceEnabled = $ServiceEnabled ConnectionGraphUsersExclusionGroup = $ConnectionGraphUsersExclusionGroup } $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body $Output } function Set-O365OrgDynamics365CustomerVoice { <# .SYNOPSIS Configures the Dynamics 365 Customer Voice settings for an Office 365 organization. .DESCRIPTION This function allows you to enable or disable the Dynamics 365 Customer Voice service for your Office 365 organization. It sends a POST request to the Office 365 admin API with the specified settings. .PARAMETER Headers Specifies the headers for the API request. Typically includes authorization tokens. .PARAMETER ReduceSurveyFatigueEnabled Specifies whether the Reduce Survey Fatigue feature should be enabled. .PARAMETER ReduceSurveyFatigueDays Specifies the number of days to reduce survey fatigue. .PARAMETER CustomDomainEmails Specifies the custom domain emails for the organization. .PARAMETER PreventPhishingAttemptsEnabled Specifies whether the Prevent Phishing Attempts feature should be enabled. .PARAMETER CollectNamesEnabled Specifies whether to collect names in the surveys. .PARAMETER RestrictSurveyAccessEnabled Specifies whether to restrict survey access. .EXAMPLE $headers = @{Authorization = "Bearer your_token"} Set-O365OrgDynamics365CustomerVoice -Headers $headers -ReduceSurveyFatigueEnabled $true -ReduceSurveyFatigueDays 30 -CustomDomainEmails @("example.com") -PreventPhishingAttemptsEnabled $false -CollectNamesEnabled $true -RestrictSurveyAccessEnabled $true This example enables the Reduce Survey Fatigue feature, sets the number of days to reduce survey fatigue to 30, adds "example.com" as a custom domain email, disables the Prevent Phishing Attempts feature, enables collecting names in the surveys, and restricts survey access for the Office 365 organization. .NOTES This function sends a POST request to the Office 365 admin API with the specified settings. #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [Parameter()][bool] $ReduceSurveyFatigueEnabled, [Parameter()][int] $ReduceSurveyFatigueDays, [Parameter()][Array] $CustomDomainEmails, [Parameter()][bool] $PreventPhishingAttemptsEnabled, [Parameter()][bool] $CollectNamesEnabled, [Parameter()][bool] $RestrictSurveyAccessEnabled ) $Uri = "https://admin.microsoft.com/admin/api/settings/apps/officeformspro" $CurrentSettings = Get-O365OrgDynamics365CustomerVoice -Headers $Headers -NoTranslation $Body = [ordered] @{ "RecordIdentityByDefaultEnabled" = $CurrentSettings.RecordIdentityByDefaultEnabled "InOrgFormsPhishingScanEnabled" = $CurrentSettings.InOrgFormsPhishingScanEnabled "OverSurveyManagementEnabled" = $CurrentSettings.OverSurveyManagementEnabled "OverSurveyManagementDays" = $CurrentSettings.OverSurveyManagementDays "CustomDomainEmails" = $CurrentSettings.CustomDomainEmails "RestrictSurveyAccessEnabled" = $CurrentSettings.RestrictSurveyAccessEnabled } if ($PSBoundParameters.ContainsKey("ReduceSurveyFatigueEnabled")) { $Body["OverSurveyManagementEnabled"] = $ReduceSurveyFatigueEnabled } if ($PSBoundParameters.ContainsKey("ReduceSurveyFatigueDays")) { $Body["OverSurveyManagementDays"] = $ReduceSurveyFatigueDays } if ($PSBoundParameters.ContainsKey("CustomDomainEmails")) { $Body["CustomDomainEmails"] = $CustomDomainEmails } if ($PSBoundParameters.ContainsKey("PreventPhishingAttemptsEnabled")) { $Body["InOrgFormsPhishingScanEnabled"] = $PreventPhishingAttemptsEnabled } if ($PSBoundParameters.ContainsKey("CollectNamesEnabled")) { $Body["RecordIdentityByDefaultEnabled"] = $CollectNamesEnabled } if ($PSBoundParameters.ContainsKey("RestrictSurveyAccessEnabled")) { $Body["RestrictSurveyAccessEnabled"] = $RestrictSurveyAccessEnabled } $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body $Output } function Set-O365OrgDynamics365SalesInsights { <# .SYNOPSIS Configures the Dynamics 365 Sales Insights settings for an Office 365 organization. .DESCRIPTION This function allows you to enable or disable the Dynamics 365 Sales Insights service for your Office 365 organization. It sends a POST request to the Office 365 admin API with the specified settings. .PARAMETER Headers Specifies the headers for the API request. Typically includes authorization tokens. .PARAMETER ServiceEnabled Specifies whether the Dynamics 365 Sales Insights service should be enabled. .EXAMPLE $headers = @{Authorization = "Bearer your_token"} Set-O365OrgDynamics365SalesInsights -Headers $headers -ServiceEnabled $true This example enables the Dynamics 365 Sales Insights service for the Office 365 organization. .NOTES This function sends a POST request to the Office 365 admin API with the specified settings. #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [Parameter(Mandatory)][bool] $ServiceEnabled ) $Uri = "https://admin.microsoft.com/admin/api/settings/apps/dci" $Body = @{ ServiceEnabled = $ServiceEnabled } $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body $Output } function Set-O365OrgForms { <# .SYNOPSIS Configures the settings for Office 365 Forms. .DESCRIPTION This function allows you to configure various settings for Office 365 Forms. It retrieves the current settings, updates them based on the provided parameters, and then sends the updated settings back to the Office 365 admin API. .PARAMETER Headers Specifies the headers for the API request. Typically includes authorization tokens. .PARAMETER BingImageSearchEnabled Specifies whether Bing Image Search should be enabled in Office 365 Forms. .PARAMETER ExternalCollaborationEnabled Specifies whether external collaboration should be enabled in Office 365 Forms. .PARAMETER ExternalSendFormEnabled Specifies whether sending forms externally should be enabled in Office 365 Forms. .PARAMETER ExternalShareCollaborationEnabled Specifies whether external share collaboration should be enabled in Office 365 Forms. .PARAMETER ExternalShareTemplateEnabled Specifies whether external share template should be enabled in Office 365 Forms. .PARAMETER ExternalShareResultEnabled Specifies whether external share result should be enabled in Office 365 Forms. .PARAMETER InOrgFormsPhishingScanEnabled Specifies whether phishing scan for in-organization forms should be enabled in Office 365 Forms. .PARAMETER InOrgSurveyIncentiveEnabled Specifies whether survey incentive for in-organization forms should be enabled in Office 365 Forms. .PARAMETER RecordIdentityByDefaultEnabled Specifies whether recording identity by default should be enabled in Office 365 Forms. .PARAMETER ResponderEditResponse Specifies whether responders should be able to edit their responses in Office 365 Forms. .EXAMPLE $headers = @{Authorization = "Bearer your_token"} Set-O365OrgForms -Headers $headers -BingImageSearchEnabled $true -ExternalCollaborationEnabled $false This example enables Bing Image Search and disables external collaboration in Office 365 Forms. .NOTES This function sends a POST request to the Office 365 admin API with the specified settings. It retrieves the current settings, updates them based on the provided parameters, and then sends the updated settings back to the API. #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [nullable[bool]] $BingImageSearchEnabled, [nullable[bool]] $ExternalCollaborationEnabled, [nullable[bool]] $ExternalSendFormEnabled, [nullable[bool]] $ExternalShareCollaborationEnabled, [nullable[bool]] $ExternalShareTemplateEnabled, [nullable[bool]] $ExternalShareResultEnabled, [nullable[bool]] $InOrgFormsPhishingScanEnabled, [nullable[bool]] $InOrgSurveyIncentiveEnabled, [nullable[bool]] $RecordIdentityByDefaultEnabled, [nullable[bool]] $ResponderEditResponse ) # We need to get current settings because it always requires all parameters # If we would just provide one parameter it would reset everything else $CurrentSettings = Get-O365OrgForms -Headers $Headers $Body = [ordered] @{ BingImageSearchEnabled = $CurrentSettings.BingImageSearchEnabled ExternalCollaborationEnabled = $CurrentSettings.ExternalCollaborationEnabled ExternalSendFormEnabled = $CurrentSettings.ExternalSendFormEnabled ExternalShareCollaborationEnabled = $CurrentSettings.ExternalShareCollaborationEnabled ExternalShareTemplateEnabled = $CurrentSettings.ExternalShareTemplateEnabled ExternalShareResultEnabled = $CurrentSettings.ExternalShareResultEnabled InOrgFormsPhishingScanEnabled = $CurrentSettings.InOrgFormsPhishingScanEnabled InOrgSurveyIncentiveEnabled = $CurrentSettings.InOrgSurveyIncentiveEnabled RecordIdentityByDefaultEnabled = $CurrentSettings.RecordIdentityByDefaultEnabled ResponderEditResponse = $CurrentSettings.ResponderEditResponse } if ($null -ne $BingImageSearchEnabled) { $Body.BingImageSearchEnabled = $BingImageSearchEnabled } if ($null -ne $ExternalCollaborationEnabled) { $Body.ExternalCollaborationEnabled = $ExternalCollaborationEnabled } if ($null -ne $ExternalSendFormEnabled) { $Body.ExternalSendFormEnabled = $ExternalSendFormEnabled } if ($null -ne $ExternalShareCollaborationEnabled) { $Body.ExternalShareCollaborationEnabled = $ExternalShareCollaborationEnabled } if ($null -ne $ExternalShareTemplateEnabled) { $Body.ExternalShareTemplateEnabled = $ExternalShareTemplateEnabled } if ($null -ne $ExternalShareResultEnabled) { $Body.ExternalShareResultEnabled = $ExternalShareResultEnabled } if ($null -ne $InOrgFormsPhishingScanEnabled) { $Body.InOrgFormsPhishingScanEnabled = $InOrgFormsPhishingScanEnabled } if ($null -ne $InOrgSurveyIncentiveEnabled) { $Body.InOrgSurveyIncentiveEnabled = $InOrgSurveyIncentiveEnabled } if ($null -ne $RecordIdentityByDefaultEnabled) { $Body.RecordIdentityByDefaultEnabled = $RecordIdentityByDefaultEnabled } if ($null -ne $ResponderEditResponse) { $Body.ResponderEditResponse = $ResponderEditResponse } $Uri = "https://admin.microsoft.com/admin/api/settings/apps/officeforms" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body $Output } function Set-O365OrgGraphDataConnect { <# .SYNOPSIS Configures the settings for Office 365 Organizational Graph Data Connect. .DESCRIPTION This function allows you to configure the settings for Office 365 Organizational Graph Data Connect. It sends a POST request to the Office 365 admin API with the specified settings. .PARAMETER Headers Specifies the headers for the API request. Typically includes authorization tokens. .PARAMETER ServiceEnabled Specifies whether the Organizational Graph Data Connect service should be enabled or disabled. .PARAMETER TenantLockBoxApproverGroup Specifies the email address of the group that will act as the Tenant LockBox approver. The email address must exist; otherwise, the API will break the cmdlet. .PARAMETER Force Forces the operation to run, ignoring current settings. Useful to overwrite settings after breaking tenant. .EXAMPLE $headers = @{Authorization = "Bearer your_token"} Set-O365OrgGraphDataConnect -Headers $headers -ServiceEnabled $true -TenantLockBoxApproverGroup "approver@example.com" -Force This example enables the Organizational Graph Data Connect service, sets the Tenant LockBox approver group to "approver@example.com", and forces the operation to run. .NOTES Ensure that the TenantLockBoxApproverGroup email address is valid and exists in your organization to avoid errors. #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [nullable[bool]] $ServiceEnabled, [string] $TenantLockBoxApproverGroup, [switch] $Force ) $Uri = "https://admin.microsoft.com/admin/api/settings/apps/o365dataplan" if ($TenantLockBoxApproverGroup -and $TenantLockBoxApproverGroup -notlike "*@*") { Write-Warning -Message "Set-O365OrgGraphDataConnect - TenantLockBoxApproverGroup must be given in email format, and it must exists." return } if (-not $Force) { $CurrentSettings = Get-O365OrgGraphDataConnect -Headers $Headers if ($CurrentSettings) { $Body = @{ "ServiceEnabled" = $CurrentSettings.ServiceEnabled "TenantLockBoxApproverGroup" = $CurrentSettings.TenantLockBoxApproverGroup } if ($null -ne $ServiceEnabled) { $Body.ServiceEnabled = $ServiceEnabled } if ($TenantLockBoxApproverGroup) { $Body.TenantLockBoxApproverGroup = $TenantLockBoxApproverGroup } } } else { $Body = @{ "ServiceEnabled" = $ServiceEnabled "TenantLockBoxApproverGroup" = $TenantLockBoxApproverGroup } } $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body $Output } function Set-O365OrgHelpdeskInformation { <# .SYNOPSIS Configures the help desk information for an Office 365 organization. .DESCRIPTION This function allows you to configure the help desk information for your Office 365 organization. It sends a POST request to the Office 365 admin API with the specified settings. .PARAMETER Headers Specifies the headers for the API request. Typically includes authorization tokens. .PARAMETER CustomHelpDeskInformationEnabled Specifies whether custom help desk information should be enabled. .PARAMETER Title Specifies the title of the custom help desk information. .PARAMETER PhoneNumber Specifies the phone number for the help desk. .PARAMETER EmailAddress Specifies the email address for the help desk. .PARAMETER SupportUrl Specifies the URL for the help desk support. .PARAMETER SupportUrlTitle Specifies the title for the support URL. .EXAMPLE $headers = @{Authorization = "Bearer your_token"} Set-O365OrgHelpdeskInformation -Headers $headers -CustomHelpDeskInformationEnabled $true -Title "Support Center" -PhoneNumber "123-456-7890" -EmailAddress "support@example.com" -SupportUrl "https://support.example.com" -SupportUrlTitle "Visit Support" This example enables custom help desk information, sets the title to "Support Center", phone number to "123-456-7890", email address to "support@example.com", support URL to "https://support.example.com", and support URL title to "Visit Support" for the Office 365 organization. #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [alias('Enabled')][bool] $CustomHelpDeskInformationEnabled, [string] $Title, [string] $PhoneNumber, [string] $EmailAddress, [string] $SupportUrl, [string] $SupportUrlTitle ) $Uri = "https://admin.microsoft.com/admin/api/Settings/company/helpdesk" $CurrentSettings = Get-O365OrgHelpdeskInformation -Headers $Headers if ($CurrentSettings) { $Body = @{ "CustomSupportEnabled" = $CurrentSettings.CustomSupportEnabled "Title" = $CurrentSettings.Title "PhoneEnabled" = $CurrentSettings.PhoneEnabled "PhoneNumber" = $CurrentSettings.PhoneNumber "EmailEnabled" = $CurrentSettings.EmailEnabled "EmailAddress" = $CurrentSettings.EmailAddress "UrlEnabled" = $CurrentSettings.UrlEnabled "SupportUrl" = $CurrentSettings.SupportUrl "SupportUrlTitle" = $CurrentSettings.SupportUrlTitle } if ($PSBoundParameters.ContainsKey('CustomHelpDeskInformationEnabled')) { $Body.CustomSupportEnabled = $CustomHelpDeskInformationEnabled } if ($PSBoundParameters.ContainsKey('Title')) { $Body.Title = $Title } if ($PSBoundParameters.ContainsKey('PhoneNumber')) { $Body.PhoneNumber = $PhoneNumber $Body.PhoneEnabled = if ($PhoneNumber) { $true } else { $false } } if ($PSBoundParameters.ContainsKey('EmailAddress')) { $Body.EmailEnabled = if ($EmailAddress) { $true } else { $false } $Body.EmailAddress = $EmailAddress } if ($PSBoundParameters.ContainsKey('SupportUrl')) { $Body.SupportUrlTitle = $SupportUrlTitle $Body.SupportUrl = $SupportUrl $Body.UrlEnabled = if ($SupportUrl) { $true } else { $false } } $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body $Output } } function Set-O365OrgInstallationOptions { <# .SYNOPSIS Configures the installation options for Microsoft Office 365 applications on user devices. .DESCRIPTION This function allows you to configure how often users receive feature updates and which Microsoft applications they can install on their devices. You can specify the update channel for Windows, and enable or disable the installation of Office and Skype for Business on both Windows and Mac devices. .PARAMETER Headers Specifies the headers for the API request. Typically includes authorization tokens. .PARAMETER WindowsBranch Specifies the update channel for Windows. Valid values are 'CurrentChannel', 'MonthlyEnterpriseChannel', and 'SemiAnnualEnterpriseChannel'. .PARAMETER WindowsOffice Specifies whether the Office suite should be enabled or disabled for Windows devices. .PARAMETER WindowsSkypeForBusiness Specifies whether Skype for Business should be enabled or disabled for Windows devices. .PARAMETER MacOffice Specifies whether the Office suite should be enabled or disabled for Mac devices. .PARAMETER MacSkypeForBusiness Specifies whether Skype for Business should be enabled or disabled for Mac devices. .EXAMPLE $headers = @{Authorization = "Bearer your_token"} Set-O365OrgInstallationOptions -Headers $headers -WindowsBranch 'CurrentChannel' -WindowsOffice $true -WindowsSkypeForBusiness $false -MacOffice $true -MacSkypeForBusiness $false This example sets the update channel for Windows to 'CurrentChannel', enables Office for both Windows and Mac devices, disables Skype for Business for both Windows and Mac devices. .NOTES It takes a while for GUI to report these changes. Be patient. #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [string][ValidateSet('CurrentChannel', 'MonthlyEnterpriseChannel', 'SemiAnnualEnterpriseChannel')] $WindowsBranch, [nullable[bool]] $WindowsOffice, [nullable[bool]] $WindowsSkypeForBusiness, [nullable[bool]] $MacOffice, [nullable[bool]] $MacSkypeForBusiness ) $ReverseBranches = @{ "CurrentChannel" = 1 "MonthlyEnterpriseChannel" = 3 "SemiAnnualEnterpriseChannel" = 2 } $Uri = "https://admin.microsoft.com/admin/api/settings/apps/usersoftware" $CurrentSettings = Get-O365OrgInstallationOptions -NoTranslation -Headers $Headers if ($CurrentSettings) { $Body = @{ UserSoftwareSettings = $CurrentSettings } if ($WindowsBranch) { $Body.UserSoftwareSettings[0].Branch = $ReverseBranches[$WindowsBranch] # we probably should update "BranchLastUpdateTime": "2021-09-02T21:54:02.953Z", # but I am not sure if it matters } if ($null -ne $WindowsOffice) { $Body.UserSoftwareSettings[0].ServiceStatusMap.'Office (includes Skype for Business),MicrosoftOffice_ClientDownload' = $WindowsOffice } if ($null -ne $WindowsSkypeForBusiness) { $Body.UserSoftwareSettings[0].ServiceStatusMap.'Skype for Business (Standalone),MicrosoftCommunicationsOnline' = $WindowsSkypeForBusiness } if ($null -ne $MacOffice) { $Body.UserSoftwareSettings[1].ServiceStatusMap.'Office,MicrosoftOffice_ClientDownload' = $MacOffice } if ($null -ne $MacSkypeForBusiness) { $Body.UserSoftwareSettings[1].LegacyServiceStatusMap.'Skype for Business (X EI Capitan 10.11 or higher),MicrosoftCommunicationsOnline' = $MacSkypeForBusiness } $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body $Output } } function Set-O365OrgM365Groups { <# .SYNOPSIS Choose how guests from outside your organization can collaborate with your users in Microsoft 365 Groups. Learn more about guest access to Microsoft 365 Groups. .DESCRIPTION This function allows you to configure how guests from outside your organization can collaborate with your users in Microsoft 365 Groups. You can specify whether to allow guest access and whether to allow guests as members. .PARAMETER Headers Specifies the headers for the API request. Typically includes authorization tokens. .PARAMETER AllowGuestAccess Specifies whether to let group owners add people outside your organization to Microsoft 365 Groups as guests. .PARAMETER AllowGuestsAsMembers Specifies whether to let guest group members access group content. .EXAMPLE $headers = @{Authorization = "Bearer your_token"} Set-O365OrgM365Groups -Headers $headers -AllowGuestAccess $true -AllowGuestsAsMembers $false This example allows group owners to add guests to Microsoft 365 Groups but does not allow guest members to access group content. .NOTES This function sends a POST request to the Office 365 admin API with the specified settings. It retrieves the current settings, updates them based on the provided parameters, and then sends the updated settings back to the API. #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [nullable[bool]] $AllowGuestAccess, [nullable[bool]] $AllowGuestsAsMembers ) $Uri = "https://admin.microsoft.com/admin/api/settings/security/o365guestuser" $CurrentSettings = Get-O365OrgM365Groups -Headers $Headers $Body = [ordered] @{ AllowGuestAccess = $CurrentSettings.AllowGuestAccess AllowGuestsAsMembers = $CurrentSettings.AllowGuestsAsMembers } if ($null -ne $AllowGuestAccess) { $Body.AllowGuestAccess = $AllowGuestAccess } if ($null -ne $AllowGuestsAsMembers) { $Body.AllowGuestsAsMembers = $AllowGuestsAsMembers } $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body $Output } function Set-O365OrgMicrosoftTeams { <# .SYNOPSIS Configures Microsoft Teams settings for an Office 365 organization. .DESCRIPTION This function allows you to configure the Microsoft Teams settings for your Office 365 organization. It sends a POST request to the Office 365 admin API with the specified settings. .PARAMETER Headers Specifies the headers for the API request. Typically includes authorization tokens. .PARAMETER AllowCalendarSharing Specifies whether calendar sharing should be allowed in Microsoft Teams. .EXAMPLE $headers = @{Authorization = "Bearer your_token"} Set-O365OrgMicrosoftTeams -Headers $headers -AllowCalendarSharing $true This example enables calendar sharing in Microsoft Teams for the Office 365 organization. .NOTES https://admin.microsoft.com/#/Settings/Services/:/Settings/L1/SkypeTeams #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [Parameter(Mandatory)][bool] $AllowCalendarSharing ) $Uri = "https://admin.microsoft.com/admin/api/settings/apps/skypeteams" $Body = Get-O365OrgMicrosoftTeams -Headers $Headers # It seems every time you check https://admin.microsoft.com/#/Settings/Services/:/Settings/L1/SkypeTeams # and you enable just 1 or two settings you need to reapply everything! so i'll # leave it for now - as it needs more investigation # $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body # $Output } function Set-O365OrgModernAuthentication { <# .SYNOPSIS Configures Modern Authentication settings for an Office 365 organization. .DESCRIPTION This function allows you to configure the Modern Authentication settings for your Office 365 organization. It sends a POST request to the Office 365 admin API with the specified settings. .PARAMETER Headers Specifies the headers for the API request. Typically includes authorization tokens. .PARAMETER EnableModernAuth Specifies whether Modern Authentication should be enabled. .PARAMETER SecureDefaults Specifies whether Secure Defaults should be enabled. .PARAMETER DisableModernAuth Specifies whether Modern Authentication should be disabled. .PARAMETER AllowBasicAuthActiveSync Specifies whether Basic Authentication for ActiveSync should be allowed. .PARAMETER AllowBasicAuthImap Specifies whether Basic Authentication for IMAP should be allowed. .PARAMETER AllowBasicAuthPop Specifies whether Basic Authentication for POP should be allowed. .PARAMETER AllowBasicAuthWebServices Specifies whether Basic Authentication for Web Services should be allowed. .PARAMETER AllowBasicAuthPowershell Specifies whether Basic Authentication for PowerShell should be allowed. .PARAMETER AllowBasicAuthAutodiscover Specifies whether Basic Authentication for Autodiscover should be allowed. .PARAMETER AllowBasicAuthMapi Specifies whether Basic Authentication for MAPI should be allowed. .PARAMETER AllowBasicAuthOfflineAddressBook Specifies whether Basic Authentication for Offline Address Book should be allowed. .PARAMETER AllowBasicAuthRpc Specifies whether Basic Authentication for RPC should be allowed. .PARAMETER AllowBasicAuthSmtp Specifies whether Basic Authentication for SMTP should be allowed. .PARAMETER AllowOutlookClient Specifies whether Basic Authentication for Outlook Client should be allowed. .EXAMPLE Set-O365OrgModernAuthentication -AllowBasicAuthImap $true -AllowBasicAuthPop $true -WhatIf This example enables Basic Authentication for IMAP and POP, and uses the WhatIf parameter to show what would happen if the command runs. .EXAMPLE Set-O365OrgModernAuthentication -AllowBasicAuthImap $false -AllowBasicAuthPop $false -Verbose -WhatIf This example disables Basic Authentication for IMAP and POP, and uses the Verbose and WhatIf parameters to show detailed information about what would happen if the command runs. .NOTES https://admin.microsoft.com/#/Settings/Services/:/Settings/L1/ModernAuthentication #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [nullable[bool]] $EnableModernAuth, #: True [nullable[bool]] $SecureDefaults, #: False [nullable[bool]] $DisableModernAuth, #: False [nullable[bool]] $AllowBasicAuthActiveSync, #: True [nullable[bool]] $AllowBasicAuthImap, #: True [nullable[bool]] $AllowBasicAuthPop, #: True [nullable[bool]] $AllowBasicAuthWebServices, #: True [nullable[bool]] $AllowBasicAuthPowershell, #: True [nullable[bool]] $AllowBasicAuthAutodiscover, #: True [nullable[bool]] $AllowBasicAuthMapi, #: True [nullable[bool]] $AllowBasicAuthOfflineAddressBook , #: True [nullable[bool]] $AllowBasicAuthRpc, #: True [nullable[bool]] $AllowBasicAuthSmtp, #: True [nullable[bool]] $AllowOutlookClient #: ) $Uri = "https://admin.microsoft.com/admin/api/services/apps/modernAuth" $CurrentSettings = Get-O365OrgModernAuthentication -Headers $Headers if (-not $CurrentSettings) { Write-Warning -Message "Set-O365ModernAuthentication - Couldn't gather current settings. Skipping setting anything." return } $Body = [ordered] @{ EnableModernAuth = $CurrentSettings.EnableModernAuth #: True SecureDefaults = $CurrentSettings.SecureDefaults #: False DisableModernAuth = $CurrentSettings.DisableModernAuth #: False AllowBasicAuthActiveSync = $CurrentSettings.AllowBasicAuthActiveSync #: True AllowBasicAuthImap = $CurrentSettings.AllowBasicAuthImap #: False AllowBasicAuthPop = $CurrentSettings.AllowBasicAuthPop #: False AllowBasicAuthWebServices = $CurrentSettings.AllowBasicAuthWebServices #: True AllowBasicAuthPowershell = $CurrentSettings.AllowBasicAuthPowershell #: True AllowBasicAuthAutodiscover = $CurrentSettings.AllowBasicAuthAutodiscover #: True AllowBasicAuthMapi = $CurrentSettings.AllowBasicAuthMapi #: True AllowBasicAuthOfflineAddressBook = $CurrentSettings.AllowBasicAuthOfflineAddressBook #: True AllowBasicAuthRpc = $CurrentSettings.AllowBasicAuthRpc #: True AllowBasicAuthSmtp = $CurrentSettings.AllowBasicAuthSmtp #: True AllowOutlookClient = $CurrentSettings.AllowOutlookClient #: True } if ($null -ne $SecureDefaults) { $Body.SecureDefaults = $SecureDefaults } if ($null -ne $EnableModernAuth) { $Body.EnableModernAuth = $EnableModernAuth } if ($null -ne $DisableModernAuth) { $Body.DisableModernAuth = $DisableModernAuth } if ($null -ne $AllowBasicAuthActiveSync) { $Body.AllowBasicAuthActiveSync = $AllowBasicAuthActiveSync } if ($null -ne $AllowBasicAuthImap) { $Body.AllowBasicAuthImap = $AllowBasicAuthImap } if ($null -ne $AllowBasicAuthPop) { $Body.AllowBasicAuthPop = $AllowBasicAuthPop } if ($null -ne $AllowBasicAuthWebServices) { $Body.AllowBasicAuthWebServices = $AllowBasicAuthWebServices } if ($null -ne $AllowBasicAuthPowershell) { $Body.AllowBasicAuthPowershell = $AllowBasicAuthPowershell } if ($null -ne $AllowBasicAuthAutodiscover) { $Body.AllowBasicAuthAutodiscover = $AllowBasicAuthAutodiscover } if ($null -ne $AllowBasicAuthMapi) { $Body.AllowBasicAuthMapi = $AllowBasicAuthMapi } if ($null -ne $AllowBasicAuthOfflineAddressBook) { $Body.AllowBasicAuthOfflineAddressBook = $AllowBasicAuthOfflineAddressBook } if ($null -ne $AllowBasicAuthRpc) { $Body.AllowBasicAuthRpc = $AllowBasicAuthRpc } if ($null -ne $AllowBasicAuthSmtp) { $Body.AllowBasicAuthSmtp = $AllowBasicAuthSmtp } if ($null -ne $AllowOutlookClient) { $Body.AllowOutlookClient = $AllowOutlookClient } $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body $Output } function Set-O365OrgMyAnalytics { <# .SYNOPSIS Configures MyAnalytics settings for an Office 365 organization. .DESCRIPTION This function allows you to configure the MyAnalytics settings for your Office 365 organization. It sends a POST request to the Office 365 admin API with the specified settings. .PARAMETER Headers Specifies the headers for the API request. Typically includes authorization tokens. .PARAMETER EnableInsightsDashboard Specifies whether the Insights Dashboard should be enabled or disabled. .PARAMETER EnableWeeklyDigest Specifies whether the Weekly Digest emails should be enabled or disabled. .PARAMETER EnableInsightsOutlookAddIn Specifies whether the Insights Outlook Add-In should be enabled or disabled. .EXAMPLE $headers = @{Authorization = "Bearer your_token"} Set-O365OrgMyAnalytics -Headers $headers -EnableInsightsDashboard $true -EnableWeeklyDigest $false -EnableInsightsOutlookAddIn $true This example enables the Insights Dashboard and the Insights Outlook Add-In, and disables the Weekly Digest emails for the Office 365 organization. #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [nullable[bool]] $EnableInsightsDashboard, [nullable[bool]] $EnableWeeklyDigest, [nullable[bool]] $EnableInsightsOutlookAddIn ) $Uri = "https://admin.microsoft.com/admin/api/services/apps/myanalytics" $CurrentSettings = Get-O365OrgMyAnalytics -Headers $Headers if ($CurrentSettings) { $Body = @{ value = @{ IsDashboardOptedOut = $CurrentSettings.EnableInsightsDashboard IsEmailOptedOut = $CurrentSettings.EnableWeeklyDigest IsAddInOptedOut = $CurrentSettings.EnableInsightsOutlookAddIn } } if ($null -ne $EnableInsightsDashboard) { $Body.value.IsDashboardOptedOut = -not $EnableInsightsDashboard } if ($null -ne $EnableWeeklyDigest) { $Body.value.IsEmailOptedOut = -not $EnableWeeklyDigest } if ($null -ne $EnableInsightsOutlookAddIn) { $Body.value.IsAddInOptedOut = -not $EnableInsightsOutlookAddIn } $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body $Output } } function Set-O365OrgNews { <# .SYNOPSIS Configures the news settings for an Office 365 organization. .DESCRIPTION This function allows you to configure the news settings for your Office 365 organization. It sends a PUT request to the Office 365 admin API with the specified settings. .PARAMETER Headers Specifies the headers for the API request. Typically includes authorization tokens. .PARAMETER ContentOnNewTabEnabled Specifies whether content on the new tab should be enabled or disabled. .PARAMETER CompanyInformationAndIndustryEnabled Specifies whether company information and industry news should be shown. .EXAMPLE $headers = @{Authorization = "Bearer your_token"} Set-O365OrgNews -Headers $headers -ContentOnNewTabEnabled $true -CompanyInformationAndIndustryEnabled $false This example enables content on the new tab and disables company information and industry news for the Office 365 organization. #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [nullable[bool]] $ContentOnNewTabEnabled, [nullable[bool]] $CompanyInformationAndIndustryEnabled ) $Uri = "https://admin.microsoft.com/admin/api/searchadminapi/news/options" $CurrentSettings = Get-O365OrgNews -Headers $Headers -NoTranslation if ($CurrentSettings) { $Body = [ordered] @{ ServiceType = 'Bing' NewsOptions = $CurrentSettings.NewsOptions } if ($null -ne $ContentOnNewTabEnabled) { $Body.NewsOptions.EdgeNTPOptions.IsOfficeContentEnabled = $ContentOnNewTabEnabled } if ($null -ne $CompanyInformationAndIndustryEnabled) { $Body.NewsOptions.EdgeNTPOptions.IsShowCompanyAndIndustry = $CompanyInformationAndIndustryEnabled } $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method PUT -Body $Body $Output } } function Set-O365OrgOfficeOnTheWeb { <# .SYNOPSIS Enables or disables Office on the web for an Office 365 tenant. .DESCRIPTION This function allows you to enable or disable the Office on the web feature for your Office 365 organization. It sends a POST request to the Office 365 admin API with the specified settings. .PARAMETER Headers Specifies the headers for the API request. Typically includes authorization tokens. .PARAMETER Enabled Specifies whether Office on the web should be enabled or disabled. This parameter is mandatory. .EXAMPLE $headers = @{Authorization = "Bearer your_token"} Set-O365OrgOfficeOnTheWeb -Headers $headers -Enabled $true This example enables Office on the web for the Office 365 organization. .EXAMPLE $headers = @{Authorization = "Bearer your_token"} Set-O365OrgOfficeOnTheWeb -Headers $headers -Enabled $false This example disables Office on the web for the Office 365 organization. #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [parameter(Mandatory)][bool] $Enabled ) $Uri = "https://admin.microsoft.com/admin/api/settings/apps/officeonline" $Body = @{ Enabled = $Enabled } $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body $Output } function Set-O365OrgOfficeProductivity { <# .SYNOPSIS Configures the Office 365 organization's productivity score feature. .DESCRIPTION This function updates the productivity score feature settings for an Office 365 organization. It allows enabling or disabling the feature, which affects the visibility of productivity scores in the Microsoft 365 admin center. .PARAMETER Headers Specifies the headers for the API request. Typically includes authorization tokens. .PARAMETER Enabled Specifies whether the productivity score feature should be enabled or disabled. Accepts a boolean value. .EXAMPLE $headers = @{Authorization = "Bearer your_token"} Set-O365OrgOfficeProductivity -Headers $headers -Enabled $true This example enables the productivity score feature for the Office 365 organization. #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [alias('ProductivityScoreOptedIn')][parameter(Mandatory)][bool] $Enabled ) $Uri = "https://admin.microsoft.com/admin/api/reports/productivityScoreCustomerOption" $Body = @{ ProductivityScoreOptedIn = $Enabled OperationTime = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ") } $null = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body } function Set-O365OrgOrganizationInformation { <# .SYNOPSIS Updates the organization information for an Office 365 tenant. .DESCRIPTION This function allows you to update various details about your Office 365 organization, such as the name, address, city, state, postal code, phone number, and technical contact email. It retrieves the current settings and updates only the specified parameters. .PARAMETER Headers Specifies the headers for the API request. Typically includes authorization tokens. .PARAMETER Name Specifies the name of the organization. .PARAMETER StreetAddress Specifies the street address of the organization. .PARAMETER ApartmentOrSuite Specifies the apartment or suite number of the organization. .PARAMETER City Specifies the city where the organization is located. .PARAMETER State Specifies the state where the organization is located. .PARAMETER PostalCode Specifies the postal code of the organization. .PARAMETER PhoneNumber Specifies the phone number of the organization. .PARAMETER TechnicalContactEmail Specifies the technical contact email for the organization. .EXAMPLE $headers = @{Authorization = "Bearer your_token"} Set-O365OrgOrganizationInformation -Headers $headers -Name "Contoso Ltd." -StreetAddress "123 Main St" -City "Redmond" -State "WA" -PostalCode "98052" -PhoneNumber "123-456-7890" -TechnicalContactEmail "admin@contoso.com" This example updates the organization information for Contoso Ltd. with the specified address, city, state, postal code, phone number, and technical contact email. #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [string] $Name, [string] $StreetAddress, [string] $ApartmentOrSuite, [string] $City, [string] $State, [string] $PostalCode, #[string] $Country, #[string] $CountryCode, #[string] $PossibleStatesOrProvinces, [string] $PhoneNumber, [string] $TechnicalContactEmail ) $Uri = "https://admin.microsoft.com/admin/api/Settings/company/profile" $CurrentSettings = Get-O365OrgOrganizationInformation -Headers $Headers if ($CurrentSettings) { $Body = @{ Name = $CurrentSettings.Name ## : Evotec Address1 = $CurrentSettings.Address1 ## : Address2 = $CurrentSettings.Address2 ## : #Address3 = $CurrentSettings.Address3 ## : #Address4 = $CurrentSettings.Address4 ## : City = $CurrentSettings.City ## : KATOWICE State = $CurrentSettings.State ## : Śląskie PostalCode = $CurrentSettings.PostalCode ## : 40- Country = $CurrentSettings.Country ## : Poland #CountryCode = $CurrentSettings.CountryCode ## : PL #PossibleStatesOrProvinces = $CurrentSettings.PossibleStatesOrProvinces ## : PhoneNumber = $CurrentSettings.PhoneNumber ## : +4 TechnicalContactEmail = $CurrentSettings.TechnicalContactEmail ## : p #DefaultDomain = $CurrentSettings.DefaultDomain ## : Language = $CurrentSettings.Language ## : en #MSPPID = $CurrentSettings.MSPPID ## : #SupportUrl = $CurrentSettings.SupportUrl ## : #SupportEmail = $CurrentSettings.SupportEmail ## : #SupportPhone = $CurrentSettings.SupportPhone ## : SupportedLanguages = $CurrentSettings.SupportedLanguages ## : {@{ID=en; Name=English; Default=True; DefaultCulture=en-US; PluralFormRules=IsOne}, @{ID=pl; Name=polski; Default=False; DefaultCulture=pl-PL; PluralFormRules=IsOne,EndsInTwoThruFourNotTweleveThruFourteen}} } if ($PSBoundParameters.ContainsKey('Name')) { $Body.Name = $Name } if ($PSBoundParameters.ContainsKey('StreetAddress')) { $Body.Address1 = $StreetAddress } if ($PSBoundParameters.ContainsKey('ApartmentOrSuite')) { $Body.Address2 = $ApartmentOrSuite } if ($PSBoundParameters.ContainsKey('City')) { $Body.City = $City } if ($PSBoundParameters.ContainsKey('State')) { $Body.State = $State } if ($PSBoundParameters.ContainsKey('PostalCode')) { $Body.PostalCode = $PostalCode } #if ($PSBoundParameters.ContainsKey('Country')) { # $Body.Country = $Country #} #if ($PSBoundParameters.ContainsKey('CountryCode')) { # $Body.CountryCode = $CountryCode #} if ($PSBoundParameters.ContainsKey('PhoneNumber')) { $Body.PhoneNumber = $PhoneNumber } if ($PSBoundParameters.ContainsKey('TechnicalContactEmail')) { $Body.TechnicalContactEmail = $TechnicalContactEmail } $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body $Output } } function Set-O365OrgPasswordExpirationPolicy { <# .SYNOPSIS Configures the password expiration policy for an Office 365 organization. .DESCRIPTION This function updates the password expiration policy settings for an Office 365 organization. It allows specifying whether passwords never expire, the number of days before passwords expire, and the number of days before users are notified of password expiration. .PARAMETER Headers Specifies the headers for the API request. Typically includes authorization tokens. .PARAMETER PasswordNeverExpires Specifies whether passwords should never expire. Accepts a nullable boolean value. .PARAMETER DaysBeforePasswordExpires Specifies the number of days before passwords expire. Accepts a nullable integer value. .PARAMETER DaysBeforeUserNotified Specifies the number of days before users are notified of password expiration. Accepts a nullable integer value. .EXAMPLE $headers = @{Authorization = "Bearer your_token"} Set-O365OrgPasswordExpirationPolicy -Headers $headers -PasswordNeverExpires $true -DaysBeforePasswordExpires 90 -DaysBeforeUserNotified 14 This example sets the password expiration policy to never expire passwords, with a notification period of 14 days before expiration. #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [Parameter()][nullable[bool]] $PasswordNeverExpires, [Parameter()][nullable[int]] $DaysBeforePasswordExpires, [Parameter()][nullable[int]] $DaysBeforeUserNotified ) $Uri = "https://admin.microsoft.com/admin/api/Settings/security/passwordpolicy" $CurrentSettings = Get-O365OrgPasswordExpirationPolicy -Headers $Headers -NoTranslation if ($CurrentSettings) { $Body = @{ ValidityPeriod = $CurrentSettings.ValidityPeriod #: 90 NotificationDays = $CurrentSettings.NotificationDays #: 14 NeverExpire = $CurrentSettings.NeverExpire #: True } if ($null -ne $DaysBeforeUserNotified) { $Body.NotificationDays = $DaysBeforeUserNotified } if ($null -ne $DaysBeforePasswordExpires) { $Body.ValidityPeriod = $DaysBeforePasswordExpires } if ($null -ne $PasswordNeverExpires) { $Body.NeverExpire = $PasswordNeverExpires } $null = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body } } function Set-O365OrgPlanner { <# .SYNOPSIS Configures the Planner settings for an Office 365 organization. .DESCRIPTION This function updates the Planner settings for an Office 365 organization. It allows enabling or disabling calendar sharing within Planner. .PARAMETER Headers Specifies the headers for the API request. Typically includes authorization tokens. .PARAMETER AllowCalendarSharing Specifies whether calendar sharing should be allowed in Planner. Accepts a boolean value. .EXAMPLE $headers = @{Authorization = "Bearer your_token"} Set-O365OrgPlanner -Headers $headers -AllowCalendarSharing $true This example enables calendar sharing in Planner. #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [Parameter(Mandatory)][bool] $AllowCalendarSharing ) $Uri = "https://admin.microsoft.com/admin/api/services/apps/planner" $Body = @{ allowCalendarSharing = $AllowCalendarSharing id = "1" isPlannerAllowed = $true } $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body $Output } function Set-O365OrgPrivacyProfile { <# .SYNOPSIS Configures the privacy profile settings for an Office 365 organization. .DESCRIPTION This function updates the privacy profile settings for an Office 365 organization. It allows specifying the privacy statement URL and the privacy contact information. .PARAMETER Headers Specifies the headers for the API request. Typically includes authorization tokens. .PARAMETER PrivacyUrl Specifies the URL of the privacy statement. Accepts a URI value. .PARAMETER PrivacyContact Specifies the contact information for privacy-related inquiries. Accepts a string value. .EXAMPLE $headers = @{Authorization = "Bearer your_token"} Set-O365OrgPrivacyProfile -Headers $headers -PrivacyUrl "https://example.com/privacy" -PrivacyContact "privacy@example.com" This example sets the privacy statement URL to "https://example.com/privacy" and the privacy contact to "privacy@example.com". #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [parameter()][uri] $PrivacyUrl, [parameter()][string] $PrivacyContact ) $Uri = "https://admin.microsoft.com/admin/api/Settings/security/privacypolicy" $Body = @{ PrivacyStatement = $PrivacyUrl PrivacyContact = $PrivacyContact } $null = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body } function Set-O365OrgPrivilegedAccess { <# .SYNOPSIS Configures the privileged access settings for an Office 365 organization. .DESCRIPTION This function updates the privileged access settings for an Office 365 organization. It allows enabling or disabling the Tenant Lockbox feature and specifying an admin group. .PARAMETER Headers Specifies the headers for the API request. Typically includes authorization tokens. .PARAMETER TenantLockBoxEnabled Specifies whether the Tenant Lockbox feature should be enabled or disabled. Accepts a nullable boolean value. .PARAMETER AdminGroup Specifies the admin group for privileged access. .EXAMPLE $headers = @{Authorization = "Bearer your_token"} Set-O365OrgPrivilegedAccess -Headers $headers -TenantLockBoxEnabled $true -AdminGroup "AdminGroupName" This example enables the Tenant Lockbox feature and sets the admin group to "AdminGroupName". #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [nullable[bool]] $TenantLockBoxEnabled, [string] $AdminGroup ) $Uri = "https://admin.microsoft.com/admin/api/Settings/security/tenantLockbox" $Body = @{ EnabledTenantLockbox = $TenantLockBoxEnabled AdminGroup = $AdminGroup Identity = $null } $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body $Output } function Set-O365OrgProject { <# .SYNOPSIS Configures the project settings for an Office 365 organization. .DESCRIPTION This function updates the project settings for an Office 365 organization. It allows enabling or disabling Roadmap and Project for the Web features. .PARAMETER Headers Specifies the headers for the API request. Typically includes authorization tokens. .PARAMETER RoadmapEnabled Specifies whether the Roadmap feature should be enabled or disabled. Accepts a nullable boolean value. .PARAMETER ProjectForTheWebEnabled Specifies whether the Project for the Web feature should be enabled or disabled. Accepts a nullable boolean value. .EXAMPLE $headers = @{Authorization = "Bearer your_token"} Set-O365OrgProject -Headers $headers -RoadmapEnabled $true -ProjectForTheWebEnabled $false This example enables the Roadmap feature and disables the Project for the Web feature. #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [nullable[bool]] $RoadmapEnabled, [nullable[bool]] $ProjectForTheWebEnabled ) $Uri = "https://admin.microsoft.com/admin/api/settings/apps/projectonline" $CurrentSettings = Get-O365OrgProject -Headers $Headers -NoTranslation if ($CurrentSettings) { $Body = @{ IsRoadmapEnabled = $CurrentSettings.IsRoadmapEnabled #: True IsModProjEnabled = $CurrentSettings.IsModProjEnabled #: True RoadmapAvailabilityError = $CurrentSettings.RoadmapAvailabilityError #: 0 ModProjAvailabilityStatus = $CurrentSettings.ModProjAvailabilityStatus #: 0 } if ($null -ne $RoadmapEnabled) { $Body.IsRoadmapEnabled = $RoadmapEnabled } if ($null -ne $ProjectForTheWebEnabled) { $Body.IsModProjEnabled = $ProjectForTheWebEnabled } $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body $Output } } function Set-O365OrgReleasePreferences { <# .SYNOPSIS Configures the release preferences for an Office 365 organization. .DESCRIPTION This function updates the release preferences for an Office 365 organization. It allows setting the release track to one of the following options: - FirstRelease - StagedRollout - None .PARAMETER Headers Specifies the headers for the API request. Typically includes authorization tokens. .PARAMETER ReleaseTrack Specifies the release track for the organization. Must be one of the following values: - FirstRelease - StagedRollout - None .EXAMPLE $headers = @{Authorization = "Bearer your_token"} Set-O365OrgReleasePreferences -Headers $headers -ReleaseTrack 'FirstRelease' This example sets the release track to 'FirstRelease'. #> [cmdletbinding()] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [parameter(Mandatory)][ValidateSet('FirstRelease', 'StagedRollout', 'None')] $ReleaseTrack ) $Uri = 'https://admin.microsoft.com/admin/api/Settings/company/releasetrack' $Body = [ordered] @{ ReleaseTrack = $ReleaseTrack ShowCompass = $false } $null = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body } function Set-O365OrgReports { <# .SYNOPSIS Configures the reporting settings for an Office 365 organization. .DESCRIPTION This function updates the reporting settings for an Office 365 organization. It allows enabling or disabling privacy settings and Power BI integration for reports. .PARAMETER Headers Specifies the headers for the API request. Typically includes authorization tokens. .PARAMETER PrivacyEnabled Specifies whether privacy settings are enabled for reports. Accepts a boolean value. .PARAMETER PowerBiEnabled Specifies whether Power BI integration is enabled for reports. Accepts a boolean value. .EXAMPLE $headers = @{Authorization = "Bearer your_token"} Set-O365OrgReports -Headers $headers -PrivacyEnabled $true -PowerBiEnabled $false This example sets the reporting settings to enable privacy settings and disable Power BI integration. #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [Parameter()][nullable[bool]] $PrivacyEnabled, [Parameter()][nullable[bool]] $PowerBiEnabled ) $Uri = "https://admin.microsoft.com/admin/api/reports/config/SetTenantConfiguration" $Body = @{ PrivacyEnabled = $PrivacyEnabled PowerBiEnabled = $PowerBiEnabled } Remove-EmptyValue -Hashtable $Body $null = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body } function Set-O365OrgScripts { <# .SYNOPSIS Configures the Office Scripts settings for an Office 365 organization. .DESCRIPTION This function updates the settings for Office Scripts in an Office 365 organization. It allows setting the permissions for users to automate their tasks, share their scripts, and run scripts in Power Automate. .PARAMETER Headers Specifies the headers for the API request. Typically includes authorization tokens. .PARAMETER LetUsersAutomateTheirTasks Specifies whether users are allowed to automate their tasks. Must be one of the following values: - Disabled - Everyone - SpecificGroup .PARAMETER LetUsersAutomateTheirTasksGroup Specifies the name of the group allowed to automate their tasks. This parameter is used if LetUsersAutomateTheirTasks is set to 'SpecificGroup'. .PARAMETER LetUsersAutomateTheirTasksGroupID Specifies the ID of the group allowed to automate their tasks. This parameter is used if LetUsersAutomateTheirTasks is set to 'SpecificGroup'. .PARAMETER LetUsersShareTheirScripts Specifies whether users are allowed to share their scripts. Must be one of the following values: - Disabled - Everyone - SpecificGroup .PARAMETER LetUsersShareTheirScriptsGroup Specifies the name of the group allowed to share their scripts. This parameter is used if LetUsersShareTheirScripts is set to 'SpecificGroup'. .PARAMETER LetUsersShareTheirScriptsGroupID Specifies the ID of the group allowed to share their scripts. This parameter is used if LetUsersShareTheirScripts is set to 'SpecificGroup'. .PARAMETER LetUsersRunScriptPowerAutomate Specifies whether users are allowed to run scripts in Power Automate. Must be one of the following values: - Disabled - Everyone - SpecificGroup .PARAMETER LetUsersRunScriptPowerAutomateGroup Specifies the name of the group allowed to run scripts in Power Automate. This parameter is used if LetUsersRunScriptPowerAutomate is set to 'SpecificGroup'. .PARAMETER LetUsersRunScriptPowerAutomateGroupID Specifies the ID of the group allowed to run scripts in Power Automate. This parameter is used if LetUsersRunScriptPowerAutomate is set to 'SpecificGroup'. .EXAMPLE $headers = @{Authorization = "Bearer your_token"} Set-O365OrgScripts -Headers $headers -LetUsersAutomateTheirTasks 'Everyone' -LetUsersShareTheirScripts 'SpecificGroup' -LetUsersShareTheirScriptsGroup 'GroupName' -LetUsersRunScriptPowerAutomate 'Disabled' This example sets the Office Scripts settings to allow everyone to automate their tasks, a specific group to share their scripts, and disables running scripts in Power Automate. #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [Parameter()][string][ValidateSet('Disabled', 'Everyone', 'SpecificGroup')] $LetUsersAutomateTheirTasks, [Parameter()][string] $LetUsersAutomateTheirTasksGroup, [Parameter()][string] $LetUsersAutomateTheirTasksGroupID, [Parameter()][string][ValidateSet('Disabled', 'Everyone', 'SpecificGroup')] $LetUsersShareTheirScripts, [Parameter()][string] $LetUsersShareTheirScriptsGroup, [Parameter()][string] $LetUsersShareTheirScriptsGroupID, [Parameter()][string][ValidateSet('Disabled', 'Everyone', 'SpecificGroup')] $LetUsersRunScriptPowerAutomate, [Parameter()][string] $LetUsersRunScriptPowerAutomateGroup, [Parameter()][string] $LetUsersRunScriptPowerAutomateGroupID ) $Uri = "https://admin.microsoft.com/admin/api/settings/apps/officescripts" $Body = [ordered] @{} if ($LetUsersAutomateTheirTasks -eq 'Disabled') { # if the user wants to disable the LetUsersAutomateTheirTasks, then we need to disable all other options as well $Body.EnabledOption = 0 $Body.ShareOption = 0 $Body.UnattendedOption = 0 } else { if ($LetUsersAutomateTheirTasks -or $LetUsersAutomateTheirTasksGroup -or $LetUsersAutomateTheirTasksGroupID) { # We check for the presence of option, but also if the user just provided a group name or ID we then assume the user wants specific group if ($LetUsersAutomateTheirTasks -eq 'SpecificGroup' -or $LetUsersAutomateTheirTasksGroup -or $LetUsersAutomateTheirTasksGroupID) { if ($LetUsersAutomateTheirTasksGroup) { # we find the id of the group from the name $Group = Get-O365Group -DisplayName $LetUsersAutomateTheirTasksGroup -Headers $Headers if ($Group.Id) { $Body.EnabledOption = 2 $Body.EnabledGroup = $Group.Id } else { Write-Warning -Message "Set-O365Scripts - LetUsersAutomateTheirTasksGroup couldn't be translated to ID. Skipping." return } } elseif ($LetUsersAutomateTheirTasksGroupID) { # we use direct ID $Body.EnabledOption = 2 $Body.EnabledGroup = $LetUsersAutomateTheirTasksGroupID } else { Write-Warning -Message "Set-O365Scripts - LetUsersAutomateTheirTasksGroup/LetUsersAutomateTheirTasksGroupID not provided. Please provide group." return } } elseif ($LetUsersAutomateTheirTasks -eq 'Everyone') { $Body.EnabledOption = 1 } elseif ($LetUsersAutomateTheirTasks -eq 'Disabled') { $Body.EnabledOption = 0 } } if ($LetUsersShareTheirScripts -or $LetUsersShareTheirScriptsGroup -or $LetUsersShareTheirScriptsGroupID) { # We check for the presence of option, but also if the user just provided a group name or ID we then assume the user wants specific group if ($LetUsersShareTheirScripts -eq 'SpecificGroup' -or $LetUsersShareTheirScriptsGroup -or $LetUsersShareTheirScriptsGroupID) { if ($LetUsersShareTheirScriptsGroup) { # we find the id of the group from the name $Group = Get-O365Group -DisplayName $LetUsersShareTheirScriptsGroup -Headers $Headers if ($Group.Id) { $Body.ShareOption = 2 $Body.ShareGroup = $Group.Id } else { Write-Warning -Message "Set-O365Scripts - LetUsersAutomateTheirTasksGroup couldn't be translated to ID. Skipping." return } } elseif ($LetUsersShareTheirScriptsGroupID) { # we use direct ID $Body.ShareOption = 2 $Body.ShareGroup = $LetUsersShareTheirScriptsGroupID } else { Write-Warning -Message "Set-O365Scripts - LetUsersShareTheirScriptsGroup/LetUsersShareTheirScriptsGroupID not provided. Please provide group." return } } elseif ($LetUsersShareTheirScripts -eq 'Everyone') { $Body.ShareOption = 1 } elseif ($LetUsersShareTheirScripts -eq 'Disabled') { $Body.ShareOption = 0 } } if ($LetUsersRunScriptPowerAutomate -or $LetUsersRunScriptPowerAutomateGroup -or $LetUsersRunScriptPowerAutomateGroupID) { # We check for the presence of option, but also if the user just provided a group name or ID we then assume the user wants specific group if ($LetUsersRunScriptPowerAutomate -eq 'SpecificGroup' -or $LetUsersRunScriptPowerAutomateGroup -or $LetUsersRunScriptPowerAutomateGroupID) { if ($LetUsersRunScriptPowerAutomateGroup) { # we find the id of the group from the name $Group = Get-O365Group -DisplayName $LetUsersRunScriptPowerAutomateGroup -Headers $Headers if ($Group.Id) { $Body.UnattendedOption = 2 $Body.UnattendedGroup = $Group.Id } else { Write-Warning -Message "Set-O365Scripts - LetUsersRunScriptPowerAutomateGroup couldn't be translated to ID. Skipping." return } } elseif ($LetUsersRunScriptPowerAutomateGroupID) { # we use direct ID $Body.UnattendedOption = 2 $Body.UnattendedGroup = $LetUsersRunScriptPowerAutomateGroupID } else { Write-Warning -Message "Set-O365Scripts - LetUsersShareTheirScriptsGroup/LetUsersRunScriptPowerAutomateGroupID not provided. Please provide group." return } } elseif ($LetUsersRunScriptPowerAutomateGroup -eq 'Everyone') { $Body.UnattendedOption = 1 } elseif ($LetUsersRunScriptPowerAutomateGroup -eq 'Disabled') { $Body.UnattendedOption = 0 } } } $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body $Output } function Set-O365OrgSendEmailNotification { <# .SYNOPSIS Sets the email notification settings for an Office 365 tenant. .DESCRIPTION This function allows you to set the email notification settings for an Office 365 tenant. You can specify the 'SendFromAddress' and whether to remove the current settings. .PARAMETER Headers The headers for the request, typically including the authorization token. This is optional. .PARAMETER SendFromAddress The email address that the notifications will be sent from. .PARAMETER Remove A switch parameter. If specified, the current settings will be removed. .EXAMPLE Set-O365OrgSendEmailNotification -SendFromAddress "admin@mydomain.com" This example sets the 'SendFromAddress' to 'admin@mydomain.com'. .EXAMPLE Set-O365OrgSendEmailNotification -Remove This example removes the current settings. .NOTES More information can be found at: https://admin.microsoft.com/Adminportal/Home?#/Settings/OrganizationProfile/:/Settings/L1/SendFromAddressSettings #> [CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'Email')] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [parameter(Mandatory, ParameterSetName = 'Email')][string] $SendFromAddress, [parameter(ParameterSetName = 'Remove')] [switch] $Remove ) $Uri = "https://admin.microsoft.com/admin/api/Settings/company/sendfromaddress" if ($Remove) { $Body = @{ ServiceEnabled = $false TenantSendFromAddress = "" } } else { $Body = @{ ServiceEnabled = if ($SendFromAddress) { $true } else { $false } TenantSendFromAddress = $SendFromAddress } } $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body if ($Output) { $Output } } function Set-O365OrgSharePoint { <# .SYNOPSIS Configures the sharing settings for SharePoint in an Office 365 organization. .DESCRIPTION This function updates the sharing settings for SharePoint in an Office 365 organization. It allows setting the collaboration type to one of the following options: - OnlyPeopleInYourOrganization - ExistingGuestsOnly - NewAndExistingGuestsOnly - Anyone .PARAMETER Headers Specifies the headers for the API request. Typically includes authorization tokens. .PARAMETER CollaborationType Specifies the type of collaboration allowed. Must be one of the following values: - OnlyPeopleInYourOrganization - ExistingGuestsOnly - NewAndExistingGuestsOnly - Anyone .EXAMPLE $headers = @{Authorization = "Bearer your_token"} Set-O365OrgSharePoint -Headers $headers -CollaborationType 'Anyone' This example sets the SharePoint collaboration type to allow sharing with anyone. #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [Parameter(Mandatory)][ValidateSet('OnlyPeopleInYourOrganization', 'ExistingGuestsOnly', 'NewAndExistingGuestsOnly', 'Anyone')][string] $CollaborationType ) $Uri = "https://admin.microsoft.com/admin/api/settings/apps/sitessharing" $ReverseTranslateCollaboration = @{ 'NewAndExistingGuestsOnly' = 2 'Anyone' = 16 'ExistingGuestsOnly' = 32 'OnlyPeopleInYourOrganization' = 1 } $Body = @{ AllowSharing = if ($CollaborationType -eq 'OnlyPeopleInYourOrganization') { $false } else { $true } CollaborationType = $ReverseTranslateCollaboration[$CollaborationType] } $null = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body } function Set-O365OrgSharing { <# .SYNOPSIS Configures the guest user policy for an Office 365 organization. .DESCRIPTION This function updates the guest user policy settings for an Office 365 organization. It allows enabling or disabling the ability for users to add new guests. .PARAMETER Headers Specifies the headers for the API request. Typically includes authorization tokens. .PARAMETER LetUsersAddNewGuests Specifies whether users are allowed to add new guests. Set to $true to allow, $false to disallow. .EXAMPLE $headers = @{Authorization = "Bearer your_token"} Set-O365OrgSharing -Headers $headers -LetUsersAddNewGuests $true This example allows users to add new guests in the Office 365 organization. #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [Parameter(Mandatory)][bool] $LetUsersAddNewGuests ) $Uri = "https://admin.microsoft.com/admin/api/settings/security/guestUserPolicy" $Body = @{ AllowGuestInvitations = $LetUsersAddNewGuests } $null = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body } function Set-O365OrgSway { <# .SYNOPSIS Configures settings for Microsoft Sway in Office 365. .DESCRIPTION This function updates the configuration settings for Microsoft Sway in Office 365. It allows enabling or disabling external sharing, people picker search, Flickr, Pickit, Wikipedia, and YouTube. .PARAMETER Headers Specifies the headers for the API request. Typically includes authorization tokens. .PARAMETER ExternalSharingEnabled Specifies whether external sharing is enabled or disabled. .PARAMETER PeoplePickerSearchEnabled Specifies whether people picker search is enabled or disabled. .PARAMETER FlickrEnabled Specifies whether Flickr integration is enabled or disabled. .PARAMETER PickitEnabled Specifies whether Pickit integration is enabled or disabled. .PARAMETER WikipediaEnabled Specifies whether Wikipedia integration is enabled or disabled. .PARAMETER YouTubeEnabled Specifies whether YouTube integration is enabled or disabled. .EXAMPLE $headers = @{Authorization = "Bearer your_token"} Set-O365OrgSway -Headers $headers -ExternalSharingEnabled $true -PeoplePickerSearchEnabled $false -FlickrEnabled $true -PickitEnabled $false -WikipediaEnabled $true -YouTubeEnabled $false This example enables external sharing, disables people picker search, enables Flickr, disables Pickit, enables Wikipedia, and disables YouTube for Microsoft Sway. #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [nullable[bool]] $ExternalSharingEnabled, [nullable[bool]] $PeoplePickerSearchEnabled, [nullable[bool]] $FlickrEnabled, [nullable[bool]] $PickitEnabled, [nullable[bool]] $WikipediaEnabled, [nullable[bool]] $YouTubeEnabled ) $Uri = "https://admin.microsoft.com/admin/api/settings/apps/Sway" $CurrentSettings = Get-O365OrgSway -Headers $Headers if ($CurrentSettings) { $Body = [ordered] @{ ExternalSharingEnabled = $CurrentSettings.ExternalSharingEnabled # : True PeoplePickerSearchEnabled = $CurrentSettings.PeoplePickerSearchEnabled # : True FlickrEnabled = $CurrentSettings.FlickrEnabled # : True PickitEnabled = $CurrentSettings.PickitEnabled # : True WikipediaEnabled = $CurrentSettings.WikipediaEnabled # : True YouTubeEnabled = $CurrentSettings.YouTubeEnabled # : True } if ($null -ne $ExternalSharingEnabled) { $Body.ExternalSharingEnabled = $ExternalSharingEnabled } if ($null -ne $FlickrEnabled) { $Body.FlickrEnabled = $FlickrEnabled } if ($null -ne $PickitEnabled) { $Body.PickitEnabled = $PickitEnabled } if ($null -ne $WikipediaEnabled) { $Body.WikipediaEnabled = $WikipediaEnabled } if ($null -ne $YouTubeEnabled) { $Body.YouTubeEnabled = $YouTubeEnabled } if ($null -ne $PeoplePickerSearchEnabled) { $Body.PeoplePickerSearchEnabled = $PeoplePickerSearchEnabled } $null = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body } } function Set-O365OrgTodo { <# .SYNOPSIS Configures settings for Microsoft To-Do in Office 365. .DESCRIPTION This function updates the configuration settings for Microsoft To-Do in Office 365. It allows enabling or disabling external join, push notifications, and external sharing. .PARAMETER Headers Specifies the headers for the API request. Typically includes authorization tokens. .PARAMETER ExternalJoinEnabled Specifies whether external join is enabled or disabled. .PARAMETER PushNotificationEnabled Specifies whether push notifications are enabled or disabled. .PARAMETER ExternalShareEnabled Specifies whether external sharing is enabled or disabled. .EXAMPLE $headers = @{Authorization = "Bearer your_token"} Set-O365OrgTodo -Headers $headers -ExternalJoinEnabled $true -PushNotificationEnabled $false -ExternalShareEnabled $true This example enables external join, disables push notifications, and enables external sharing for Microsoft To-Do. #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [nullable[bool]] $ExternalJoinEnabled, [nullable[bool]] $PushNotificationEnabled, [nullable[bool]] $ExternalShareEnabled ) $Uri = "https://admin.microsoft.com/admin/api/services/apps/todo" $CurrentSettings = Get-O365OrgToDo -Headers $Headers if ($CurrentSettings) { $Body = @{ IsExternalJoinEnabled = $CurrentSettings.IsExternalJoinEnabled IsPushNotificationEnabled = $CurrentSettings.IsPushNotificationEnabled IsExternalShareEnabled = $CurrentSettings.IsExternalShareEnabled } if ($null -ne $ExternalJoinEnabled) { $Body.IsExternalJoinEnabled = $ExternalJoinEnabled } if ($null -ne $PushNotificationEnabled) { $Body.IsPushNotificationEnabled = $PushNotificationEnabled } if ($null -ne $ExternalShareEnabled) { $Body.IsExternalShareEnabled = $ExternalShareEnabled } $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body $Output } } function Set-O365OrgUserConsentApps { <# .SYNOPSIS Configures user consent settings for integrated apps in Office 365. .DESCRIPTION This function updates the configuration settings for user consent to integrated apps in Office 365. It allows enabling or disabling user consent to apps. .PARAMETER Headers Specifies the headers for the API request. Typically includes authorization tokens. .PARAMETER UserConsentToAppsEnabled Specifies whether user consent to apps is enabled or disabled. This parameter is mandatory. .EXAMPLE $headers = @{Authorization = "Bearer your_token"} Set-O365OrgUserConsentApps -Headers $headers -UserConsentToAppsEnabled $true This example enables user consent to integrated apps. #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [ValidateSet('DoNotAllow', 'AllowLimited', 'AllowAll')] [parameter(Mandatory)][string] $UserConsentToApps ) $Uri = "https://graph.microsoft.com/v1.0/policies/authorizationPolicy" [Array] $CurrentSettings = Get-O365OrgUserConsentApps -Headers $Headers -Native if ($null -eq $CurrentSettings) { Write-Warning "No current settings found. Please run Get-O365OrgUserConsentApps first to see what's wrong." return } if ($UserConsentToApps -eq 'DoNotAllow') { [Array] $NewSettings = foreach ($Setting in $CurrentSettings) { if ($Setting -eq "ManagePermissionGrantsForSelf.microsoft-user-default-low") { } elseif ($CurrentSettings -contains "ManagePermissionGrantsForSelf.microsoft-user-default-legacy") { } else { $Setting } } $Body = @{ defaultUserRolePermissions = @{ permissionGrantPoliciesAssigned = @( #"ManagePermissionGrantsForOwnedResource.microsoft-dynamically-managed-permissions-for-chat", #"ManagePermissionGrantsForOwnedResource.microsoft-dynamically-managed-permissions-for-team" $NewSettings | Sort-Object -Unique ) } } } elseif ($UserConsentToApps -eq 'AllowLimited') { [Array] $NewSettings = foreach ($Setting in $CurrentSettings) { if ($Setting -eq "ManagePermissionGrantsForSelf.microsoft-user-default-low") { return } elseif ($CurrentSettings -contains "ManagePermissionGrantsForSelf.microsoft-user-default-legacy") { } else { $Setting } } if ($NewSettings -notcontains "ManagePermissionGrantsForSelf.microsoft-user-default-low") { $NewSettings += "ManagePermissionGrantsForSelf.microsoft-user-default-low" } $Body = @{ defaultUserRolePermissions = @{ permissionGrantPoliciesAssigned = @( #"ManagePermissionGrantsForOwnedResource.microsoft-dynamically-managed-permissions-for-chat", #"ManagePermissionGrantsForOwnedResource.microsoft-dynamically-managed-permissions-for-team", #"ManagePermissionGrantsForSelf.microsoft-user-default-low" $NewSettings | Sort-Object -Unique ) } } } elseif ($UserConsentToApps -eq 'AllowAll') { [Array] $NewSettings = foreach ($Setting in $CurrentSettings) { if ($Setting -eq "ManagePermissionGrantsForSelf.microsoft-user-default-low") { } elseif ($CurrentSettings -contains "ManagePermissionGrantsForSelf.microsoft-user-default-legacy") { return } else { $Setting } } if ($NewSettings -notcontains "ManagePermissionGrantsForSelf.microsoft-user-default-legacy") { $NewSettings += "ManagePermissionGrantsForSelf.microsoft-user-default-legacy" } $Body = @{ defaultUserRolePermissions = @{ permissionGrantPoliciesAssigned = @( #"ManagePermissionGrantsForOwnedResource.microsoft-dynamically-managed-permissions-for-chat", #"ManagePermissionGrantsForOwnedResource.microsoft-dynamically-managed-permissions-for-team", #"ManagePermissionGrantsForSelf.microsoft-user-default-legacy" $NewSettings | Sort-Object -Unique ) } } } $null = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method PATCH -Body $Body } function Set-O365OrgUserOwnedApps { <# .SYNOPSIS Configures settings for user-owned apps in Office 365. .DESCRIPTION This function updates the configuration settings for user-owned apps in Office 365. It allows enabling or disabling user access to the Office Store, starting trials, and auto-claiming licenses. .PARAMETER Headers Specifies the headers for the API request. Typically includes authorization tokens. .PARAMETER LetUsersAccessOfficeStore Specifies whether users are allowed to access the Office Store. .PARAMETER LetUsersStartTrials Specifies whether users are allowed to start trials. .PARAMETER LetUsersAutoClaimLicenses Specifies whether users are allowed to auto-claim licenses. .EXAMPLE $headers = @{Authorization = "Bearer your_token"} Set-O365OrgUserOwnedApps -Headers $headers -LetUsersAccessOfficeStore $true -LetUsersStartTrials $false -LetUsersAutoClaimLicenses $true This example enables user access to the Office Store, disables starting trials, and enables auto-claiming licenses. #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [nullable[bool]] $LetUsersAccessOfficeStore, [nullable[bool]] $LetUsersStartTrials, [nullable[bool]] $LetUsersAutoClaimLicenses ) if ($null -ne $LetUsersAccessOfficeStore) { $Uri = "https://admin.microsoft.com/admin/api/settings/apps/store" $Body = @{ Enabled = $LetUsersAccessOfficeStore } $null = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body } if ($null -ne $LetUsersStartTrials) { $TrialState = $LetUsersStartTrials.ToString().ToLower() $Uri = "https://admin.microsoft.com/admin/api/storesettings/iwpurchase/$TrialState" $null = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method PUT #-Body $Body } if ($null -ne $LetUsersAutoClaimLicenses) { $Uri = "https://admin.microsoft.com/fd/m365licensing/v1/policies/autoclaim" $Body = @{ policyValue = if ($LetUsersAutoClaimLicenses -eq $true) { 'Enabled' } else { 'Disabled' } } $null = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body } } function Set-O365OrgVivaLearning { <# .SYNOPSIS Configures the Viva Learning feature for Office 365. .DESCRIPTION This function updates the settings for the Viva Learning feature in Office 365. It allows configuring various options such as learning sources, diagnostic data sharing preferences, and enabling or disabling specific learning platforms. .PARAMETER Headers Specifies the headers for the API request. Typically includes authorization tokens. .PARAMETER LinkedInLearningEnabled Indicates whether LinkedIn Learning is enabled. Accepts $true or $false. .PARAMETER MicrosoftLearnEnabled Indicates whether Microsoft Learn is enabled. Accepts $true or $false. .PARAMETER Microsoft365TrainingEnabled Indicates whether Microsoft 365 Training is enabled. Accepts $true or $false. .PARAMETER IsOptionalDiagnosticDataEnabled Indicates whether optional diagnostic data sharing is enabled. Accepts $true or $false. .EXAMPLE $headers = @{Authorization = "Bearer your_token"} Set-O365OrgVivaLearning -Headers $headers -LinkedInLearningEnabled $true -MicrosoftLearnEnabled $true -Microsoft365TrainingEnabled $true -IsOptionalDiagnosticDataEnabled $true This example enables all learning platforms and optional diagnostic data sharing. #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [bool] $LinkedInLearningEnabled, [bool] $MicrosoftLearnEnabled, [bool] $Microsoft365TrainingEnabled, [bool] $IsOptionalDiagnosticDataEnabled ) # We need to get current settings because it always requires all parameters # If we would just provide one parameter it would reset everything else $CurrentSettings = Get-O365OrgVivaLearning -Headers $Headers $Body = [ordered] @{ CornerstoneClientId = $CurrentSettings.CornerstoneClientId CornerstoneClientSecret = $CurrentSettings.CornerstoneClientSecret CornerstoneDisplayName = $CurrentSettings.CornerstoneDisplayName CornerstoneEnabled = $CurrentSettings.CornerstoneEnabled CornerstoneExternalErrorCode = $CurrentSettings.CornerstoneExternalErrorCode CornerstoneHostUrl = $CurrentSettings.CornerstoneHostUrl CornerstoneIngestionPipelineStatus = $CurrentSettings.CornerstoneIngestionPipelineStatus CornerstoneLastIngestionProcessDate = $CurrentSettings.CornerstoneLastIngestionProcessDate CourseraEnabled = $CurrentSettings.CourseraEnabled DefaultRegion = $CurrentSettings.DefaultRegion EdCastClientHostUrl = $CurrentSettings.EdCastClientHostUrl EdCastClientId = $CurrentSettings.EdCastClientId EdCastClientSecret = $CurrentSettings.EdCastClientSecret EdCastEnabled = $CurrentSettings.EdCastEnabled EdCastExternalErrorCode = $CurrentSettings.EdCastExternalErrorCode EdCastIngestionPipelineStatus = $CurrentSettings.EdCastIngestionPipelineStatus EdCastLastIngestionProcessDate = $CurrentSettings.EdCastLastIngestionProcessDate EdCastUserEmail = $CurrentSettings.EdCastUserEmail EdXEnabled = $CurrentSettings.EdXEnabled Go1ClientHostUrl = $CurrentSettings.Go1ClientHostUrl Go1ClientId = $CurrentSettings.Go1ClientId Go1ClientSecret = $CurrentSettings.Go1ClientSecret Go1Enabled = $CurrentSettings.Go1Enabled Go1ExternalErrorCode = $CurrentSettings.Go1ExternalErrorCode Go1IngestionPipelineStatus = $CurrentSettings.Go1IngestionPipelineStatus Go1LastIngestionProcessDate = $CurrentSettings.Go1LastIngestionProcessDate InfosecEnabled = $CurrentSettings.InfosecEnabled Is3PLearningSourceEnabled = $CurrentSettings.Is3PLearningSourceEnabled IsLMSLearningSourceEnabled = $CurrentSettings.IsLMSLearningSourceEnabled IsMultiGeo = $CurrentSettings.IsMultiGeo IsOptionalDiagnosticDataEnabled = $CurrentSettings.IsOptionalDiagnosticDataEnabled IsSharePointSourceEnabled = $CurrentSettings.IsSharePointSourceEnabled IsSkillsoftEnabled = $CurrentSettings.IsSkillsoftEnabled IsTier13PsEnabled = $CurrentSettings.IsTier13PsEnabled JbaEnabled = $CurrentSettings.JbaEnabled LinkedInLearningEnabled = $CurrentSettings.LinkedInLearningEnabled Microsoft365TrainingEnabled = $CurrentSettings.Microsoft365TrainingEnabled MicrosoftLearnEnabled = $CurrentSettings.MicrosoftLearnEnabled PluralsightEnabled = $CurrentSettings.PluralsightEnabled SabaClientId = $CurrentSettings.SabaClientId SabaClientSecret = $CurrentSettings.SabaClientSecret SabaDisplayName = $CurrentSettings.SabaDisplayName SabaEnabled = $CurrentSettings.SabaEnabled SabaExternalErrorCode = $CurrentSettings.SabaExternalErrorCode SabaHostUrl = $CurrentSettings.SabaHostUrl SabaIngestionPipelineStatus = $CurrentSettings.SabaIngestionPipelineStatus SabaLastIngestionProcessDate = $CurrentSettings.SabaLastIngestionProcessDate SabaPassword = $CurrentSettings.SabaPassword SabaUsername = $CurrentSettings.SabaUsername SharePointEnabled = $CurrentSettings.SharePointEnabled SharePointUrl = $CurrentSettings.SharePointUrl SkillsoftEnabled = $CurrentSettings.SkillsoftEnabled SkillsoftExternalErrorCode = $CurrentSettings.SkillsoftExternalErrorCode SkillsoftIngestionPipelineStatus = $CurrentSettings.SkillsoftIngestionPipelineStatus SkillsoftLastIngestionProcessDate = $CurrentSettings.SkillsoftLastIngestionProcessDate SkillsoftOrganizationId = $CurrentSettings.SkillsoftOrganizationId SkillsoftServiceAccountKey = $CurrentSettings.SkillsoftServiceAccountKey SuccessFactorsClientDestinationUrl = $CurrentSettings.SuccessFactorsClientDestinationUrl SuccessFactorsClientHostUrl = $CurrentSettings.SuccessFactorsClientHostUrl SuccessFactorsCompanyID = $CurrentSettings.SuccessFactorsCompanyID SuccessFactorsDisplayName = $CurrentSettings.SuccessFactorsDisplayName SuccessFactorsEnabled = $CurrentSettings.SuccessFactorsEnabled SuccessFactorsExternalErrorCode = $CurrentSettings.SuccessFactorsExternalErrorCode SuccessFactorsFolderPath = $CurrentSettings.SuccessFactorsFolderPath SuccessFactorsHostUrl = $CurrentSettings.SuccessFactorsHostUrl SuccessFactorsIngestionPipelineStatus = $CurrentSettings.SuccessFactorsIngestionPipelineStatus SuccessFactorsLastIngestionProcessDate = $CurrentSettings.SuccessFactorsLastIngestionProcessDate SuccessFactorsPassword = $CurrentSettings.SuccessFactorsPassword SuccessFactorsPrivateKey = $CurrentSettings.SuccessFactorsPrivateKey SuccessFactorsPrivateKeyPassphrase = $CurrentSettings.SuccessFactorsPrivateKeyPassphrase SuccessFactorsUsername = $CurrentSettings.SuccessFactorsUsername TenantSpecificSkillsoftEnabled = $CurrentSettings.TenantSpecificSkillsoftEnabled UdemyClientHostUrl = $CurrentSettings.UdemyClientHostUrl UdemyClientId = $CurrentSettings.UdemyClientId UdemyClientSecret = $CurrentSettings.UdemyClientSecret UdemyEnabled = $CurrentSettings.UdemyEnabled UdemyExternalErrorCode = $CurrentSettings.UdemyExternalErrorCode UdemyIngestionPipelineStatus = $CurrentSettings.UdemyIngestionPipelineStatus UdemyLastIngestionProcessDate = $CurrentSettings.UdemyLastIngestionProcessDate UdemyOrganizationId = $CurrentSettings.UdemyOrganizationId } if ($PSBoundParameters.ContainsKey('LinkedInLearningEnabled')) { $Body.LinkedInLearningEnabled = $LinkedInLearningEnabled } if ($PSBoundParameters.ContainsKey('MicrosoftLearnEnabled')) { $Body.MicrosoftLearnEnabled = $MicrosoftLearnEnabled } if ($PSBoundParameters.ContainsKey('Microsoft365TrainingEnabled')) { $Body.Microsoft365TrainingEnabled = $Microsoft365TrainingEnabled } if ($PSBoundParameters.ContainsKey('IsOptionalDiagnosticDataEnabled')) { $Body.IsOptionalDiagnosticDataEnabled = $IsOptionalDiagnosticDataEnabled } $Uri = "https://admin.microsoft.com/admin/api/settings/apps/learning" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body $Output } function Set-O365OrgWhiteboard { <# .SYNOPSIS Configures settings for the Office 365 Whiteboard application. .DESCRIPTION This function updates the configuration settings for the Office 365 Whiteboard application. It allows enabling or disabling the Whiteboard, setting diagnostic data sharing preferences, and configuring related features like connected experiences, board sharing, and OneDrive storage. .PARAMETER Headers Specifies the headers for the API request. Typically includes authorization tokens. .PARAMETER WhiteboardEnabled Specifies whether the Whiteboard is enabled or disabled. .PARAMETER DiagnosticData Specifies the level of diagnostic data allowed. Valid values are 'Neither', 'Required', 'Optional'. .PARAMETER OptionalConnectedExperiences Specifies whether optional connected experiences are enabled. .PARAMETER BoardSharingEnabled Specifies whether board sharing is enabled. .PARAMETER OneDriveStorageEnabled Specifies whether OneDrive storage is enabled for Whiteboard. .EXAMPLE $headers = @{Authorization = "Bearer your_token"} Set-O365OrgWhiteboard -Headers $headers -WhiteboardEnabled $true -DiagnosticData 'Optional' -OptionalConnectedExperiences $true -BoardSharingEnabled $true -OneDriveStorageEnabled $true This example enables the Whiteboard with optional diagnostic data, connected experiences, board sharing, and OneDrive storage. #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [nullable[bool]] $WhiteboardEnabled, [ValidateSet('Neither', 'Required', 'Optional')]$DiagnosticData, [nullable[bool]] $OptionalConnectedExperiences, [nullable[bool]] $BoardSharingEnabled, [nullable[bool]] $OneDriveStorageEnabled ) $Uri = "https://admin.microsoft.com/admin/api/settings/apps/whiteboard" $CurrentSettings = Get-O365OrgWhiteboard -Headers $Headers -NoTranslation $Body = [ordered] @{ IsEnabled = $CurrentSettings.IsEnabled # : True IsClaimEnabled = $CurrentSettings.IsClaimEnabled #: True IsSharePointDefault = $CurrentSettings.IsSharePointDefault #: False # This always seems to be 0, but i'll let it read it from Get-O365OrgWhiteboard NonTenantAccess = $CurrentSettings.NonTenantAccess #: 0 TelemetryPolicy = $CurrentSettings.TelemetryPolicy #: 2 AreConnectedServicesEnabled = $CurrentSettings.AreConnectedServicesEnabled #: True } if ($null -ne $WhiteboardEnabled) { $Body.IsEnabled = $WhiteboardEnabled } if ($DiagnosticData) { $ReverseTranslateTelemetry = @{ 'Neither' = 0 'Required' = 1 'Optional' = 2 } $Body.TelemetryPolicy = $ReverseTranslateTelemetry[$DiagnosticData] } if ($null -ne $OptionalConnectedExperiences) { $Body.AreConnectedServicesEnabled = $OptionalConnectedExperiences } if ($null -ne $BoardSharingEnabled) { $Body.IsClaimEnabled = $BoardSharingEnabled } if ($null -ne $OneDriveStorageEnabled) { $Body.IsSharePointDefault = $OneDriveStorageEnabled } $null = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body } function Set-O365PasswordReset { <# .SYNOPSIS Configures password reset settings for Office 365. .DESCRIPTION This function updates the settings for password reset policies in Office 365. It allows configuring various options such as authentication methods, notification settings, and security questions. .PARAMETER Headers Specifies the headers for the API request. Typically includes authorization tokens. .PARAMETER EnablementType Specifies the type of enablement for the password reset policy. .PARAMETER NumberOfAuthenticationMethodsRequired Specifies the number of authentication methods required for password reset. .PARAMETER EmailOptionEnabled Indicates whether the email option is enabled for password reset. .PARAMETER MobilePhoneOptionEnabled Indicates whether the mobile phone option is enabled for password reset. .PARAMETER OfficePhoneOptionEnabled Indicates whether the office phone option is enabled for password reset. .PARAMETER SecurityQuestionsOptionEnabled Indicates whether the security questions option is enabled for password reset. .PARAMETER MobileAppNotificationEnabled Indicates whether the mobile app notification option is enabled for password reset. .PARAMETER MobileAppCodeEnabled Indicates whether the mobile app code option is enabled for password reset. .PARAMETER NumberOfQuestionsToRegister Specifies the number of security questions required to register for password reset. .PARAMETER NumberOfQuestionsToReset Specifies the number of security questions required to reset the password. .PARAMETER RegistrationRequiredOnSignIn Indicates whether registration is required on sign-in. .PARAMETER RegistrationReconfirmIntevalInDays Specifies the interval in days for reconfirming registration. .PARAMETER SkipRegistrationAllowed Indicates whether skipping registration is allowed. .PARAMETER SkipRegistrationMaxAllowedDays Specifies the maximum number of days allowed for skipping registration. .PARAMETER CustomizeHelpdeskLink Indicates whether the helpdesk link is customized. .PARAMETER CustomHelpdeskEmailOrUrl Specifies the custom helpdesk email or URL. .PARAMETER NotifyUsersOnPasswordReset Indicates whether users are notified on password reset. .PARAMETER NotifyOnAdminPasswordReset Indicates whether administrators are notified on password reset. .PARAMETER PasswordResetEnabledGroupIds Specifies the group IDs for which password reset is enabled. .PARAMETER PasswordResetEnabledGroupName Specifies the group name for which password reset is enabled. .PARAMETER EmailOptionAllowed Indicates whether the email option is allowed for password reset. .PARAMETER MobilePhoneOptionAllowed Indicates whether the mobile phone option is allowed for password reset. .PARAMETER OfficePhoneOptionAllowed Indicates whether the office phone option is allowed for password reset. .PARAMETER SecurityQuestionsOptionAllowed Indicates whether the security questions option is allowed for password reset. .PARAMETER MobileAppNotificationOptionAllowed Indicates whether the mobile app notification option is allowed for password reset. .PARAMETER MobileAppCodeOptionAllowed Indicates whether the mobile app code option is allowed for password reset. .EXAMPLE $headers = @{Authorization = "Bearer your_token"} Set-O365PasswordReset -Headers $headers -EnablementType 1 -NumberOfAuthenticationMethodsRequired 2 -EmailOptionEnabled $true This example configures the password reset policy with the specified settings. #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [nullable[int]] $EnablementType , # = $CurrentSettings.enablementType #: 1 [nullable[int]]$NumberOfAuthenticationMethodsRequired, # = $CurrentSettings.numberOfAuthenticationMethodsRequired #: 1 [nullable[bool]] $EmailOptionEnabled , # = $CurrentSettings.emailOptionEnabled #: True [nullable[bool]] $MobilePhoneOptionEnabled , # = $CurrentSettings.mobilePhoneOptionEnabled #: True [nullable[bool]] $OfficePhoneOptionEnabled , # = $CurrentSettings.officePhoneOptionEnabled #: False [nullable[bool]] $SecurityQuestionsOptionEnabled , # = $CurrentSettings.securityQuestionsOptionEnabled #: False [nullable[bool]] $MobileAppNotificationEnabled , # = $CurrentSettings.mobileAppNotificationEnabled #: False [nullable[bool]] $MobileAppCodeEnabled , # = $CurrentSettings.mobileAppCodeEnabled #: True [nullable[int]] $NumberOfQuestionsToRegister , # = $CurrentSettings.numberOfQuestionsToRegister #: 5 [nullable[int]] $NumberOfQuestionsToReset , # = $CurrentSettings.numberOfQuestionsToReset #: 3 [nullable[bool]] $RegistrationRequiredOnSignIn , # = $CurrentSettings.registrationRequiredOnSignIn #: True [nullable[int]]$RegistrationReconfirmIntevalInDays , # = $CurrentSettings.registrationReconfirmIntevalInDays #: 180 [nullable[bool]] $SkipRegistrationAllowed , # = $CurrentSettings.skipRegistrationAllowed #: True [nullable[int]] $SkipRegistrationMaxAllowedDays , # = $CurrentSettings.skipRegistrationMaxAllowedDays #: 7 [nullable[bool]] $CustomizeHelpdeskLink , # = $CurrentSettings.customizeHelpdeskLink #: False [string] $CustomHelpdeskEmailOrUrl , # = $CurrentSettings.customHelpdeskEmailOrUrl #: [nullable[bool]] $NotifyUsersOnPasswordReset , # = $CurrentSettings.notifyUsersOnPasswordReset #: True [nullable[bool]] $NotifyOnAdminPasswordReset , # = $CurrentSettings.notifyOnAdminPasswordReset #: True [string] $PasswordResetEnabledGroupIds , # = $CurrentSettings.passwordResetEnabledGroupIds #: {b6cdb9c3-d660-4558-bcfd-82c14a986b56} [string] $PasswordResetEnabledGroupName , # = $CurrentSettings.passwordResetEnabledGroupName #: # don't have details about those. needs investigations # $securityQuestions , # = $CurrentSettings.securityQuestions #: {} #$registrationConditionalAccessPolicies, # = $CurrentSettings.registrationConditionalAccessPolicies #: {} [nullable[bool]] $EmailOptionAllowed , # = $CurrentSettings.emailOptionAllowed #: True [nullable[bool]] $MobilePhoneOptionAllowed , # = $CurrentSettings.mobilePhoneOptionAllowed #: True [nullable[bool]] $OfficePhoneOptionAllowed , # = $CurrentSettings.officePhoneOptionAllowed #: True [nullable[bool]] $SecurityQuestionsOptionAllowed , # = $CurrentSettings.securityQuestionsOptionAllowed #: True [nullable[bool]] $MobileAppNotificationOptionAllowed , # = $CurrentSettings.mobileAppNotificationOptionAllowed #: True [nullable[bool]] $MobileAppCodeOptionAllowed # = $CurrentSettings.mobileAppCodeOptionAllowed #: True ) $Uri = "https://main.iam.ad.ext.azure.com/api/PasswordReset/PasswordResetPolicies" $CurrentSettings = Get-O365PasswordReset -Headers $Headers if ($CurrentSettings.objectId -ne 'default') { Write-Warning -Message "Set-O365PasswordReset - Getting current settings failed. Skipping changes." return } $Body = [ordered] @{ objectId = $CurrentSettings.objectId #: default enablementType = $CurrentSettings.enablementType #: 1 numberOfAuthenticationMethodsRequired = $CurrentSettings.numberOfAuthenticationMethodsRequired #: 1 emailOptionEnabled = $CurrentSettings.emailOptionEnabled #: True mobilePhoneOptionEnabled = $CurrentSettings.mobilePhoneOptionEnabled #: True officePhoneOptionEnabled = $CurrentSettings.officePhoneOptionEnabled #: False securityQuestionsOptionEnabled = $CurrentSettings.securityQuestionsOptionEnabled #: False mobileAppNotificationEnabled = $CurrentSettings.mobileAppNotificationEnabled #: False mobileAppCodeEnabled = $CurrentSettings.mobileAppCodeEnabled #: True numberOfQuestionsToRegister = $CurrentSettings.numberOfQuestionsToRegister #: 5 numberOfQuestionsToReset = $CurrentSettings.numberOfQuestionsToReset #: 3 registrationRequiredOnSignIn = $CurrentSettings.registrationRequiredOnSignIn #: True registrationReconfirmIntevalInDays = $CurrentSettings.registrationReconfirmIntevalInDays #: 180 skipRegistrationAllowed = $CurrentSettings.skipRegistrationAllowed #: True skipRegistrationMaxAllowedDays = $CurrentSettings.skipRegistrationMaxAllowedDays #: 7 customizeHelpdeskLink = $CurrentSettings.customizeHelpdeskLink #: False customHelpdeskEmailOrUrl = $CurrentSettings.customHelpdeskEmailOrUrl #: notifyUsersOnPasswordReset = $CurrentSettings.notifyUsersOnPasswordReset #: True notifyOnAdminPasswordReset = $CurrentSettings.notifyOnAdminPasswordReset #: True passwordResetEnabledGroupIds = $CurrentSettings.passwordResetEnabledGroupIds #: {b6cdb9c3-d660-4558-bcfd-82c14a986b56} passwordResetEnabledGroupName = $CurrentSettings.passwordResetEnabledGroupName #: securityQuestions = $CurrentSettings.securityQuestions #: {} registrationConditionalAccessPolicies = $CurrentSettings.registrationConditionalAccessPolicies #: {} emailOptionAllowed = $CurrentSettings.emailOptionAllowed #: True mobilePhoneOptionAllowed = $CurrentSettings.mobilePhoneOptionAllowed #: True officePhoneOptionAllowed = $CurrentSettings.officePhoneOptionAllowed #: True securityQuestionsOptionAllowed = $CurrentSettings.securityQuestionsOptionAllowed #: True mobileAppNotificationOptionAllowed = $CurrentSettings.mobileAppNotificationOptionAllowed #: True mobileAppCodeOptionAllowed = $CurrentSettings.mobileAppCodeOptionAllowed #: True } if ($null -ne $EnablementType) { $Body.enablementType = $EnablementType } if ($null -ne $NumberOfAuthenticationMethodsRequired) { $Body.numberOfAuthenticationMethodsRequired = $NumberOfAuthenticationMethodsRequired } if ($null -ne $EmailOptionEnabled) { $Body.emailOptionEnabled = $EmailOptionEnabled } if ($null -ne $MobilePhoneOptionEnabled) { $Body.mobilePhoneOptionEnabled = $MobilePhoneOptionEnabled } if ($null -ne $OfficePhoneOptionEnabled) { $Body.officePhoneOptionEnabled = $OfficePhoneOptionEnabled } if ($null -ne $SecurityQuestionsOptionEnabled) { $Body.securityQuestionsOptionEnabled = $SecurityQuestionsOptionEnabled } if ($null -ne $MobileAppNotificationEnabled) { $Body.mobileAppNotificationEnabled = $MobileAppNotificationEnabled } if ($null -ne $MobileAppCodeEnabled) { $Body.mobileAppCodeEnabled = $MobileAppCodeEnabled } if ($null -ne $NumberOfQuestionsToRegister) { $Body.numberOfQuestionsToRegister = $NumberOfQuestionsToRegister } if ($null -ne $NumberOfQuestionsToReset) { $Body.numberOfQuestionsToReset = $NumberOfQuestionsToReset } if ($null -ne $RegistrationRequiredOnSignIn) { $Body.registrationRequiredOnSignIn = $RegistrationRequiredOnSignIn } if ($null -ne $RegistrationReconfirmIntevalInDays) { $Body.registrationReconfirmIntevalInDays = $RegistrationReconfirmIntevalInDays } if ($null -ne $SkipRegistrationAllowed) { $Body.skipRegistrationAllowed = $SkipRegistrationAllowed } if ($null -ne $SkipRegistrationMaxAllowedDays) { $Body.skipRegistrationMaxAllowedDays = $SkipRegistrationMaxAllowedDays } if ($CustomizeHelpdeskLink) { $Body.customizeHelpdeskLink = $CustomizeHelpdeskLink } if ($null -ne $CustomHelpdeskEmailOrUrl) { $Body.customHelpdeskEmailOrUrl = $CustomHelpdeskEmailOrUrl } if ($null -ne $NotifyUsersOnPasswordReset) { $Body.notifyUsersOnPasswordReset = $NotifyUsersOnPasswordReset } if ($null -ne $NotifyOnAdminPasswordReset) { $Body.notifyOnAdminPasswordReset = $NotifyOnAdminPasswordReset } if ($PasswordResetEnabledGroupName) { # We should find an easy way to find ID of a group and set it here $Group = Get-O365Group -DisplayName $PasswordResetEnabledGroupName if ($Group.id) { if ($Group -is [PSCustomObject]) { # Not implemented yet $Body.passwordResetEnabledGroupIds = @( # Query for group id from group name $PasswordResetEnabledGroupName $Group.id ) } else { Write-Warning -Message "Set-O365PasswordReset - Group with name $PasswordResetEnabledGroupName not found or too many groups returned ($($Group.id -join ", "))" return } } else { Write-Warning -Message "Set-O365PasswordReset - Group with name $PasswordResetEnabledGroupName not found." return } } elseif ($PasswordResetEnabledGroupIds) { $Body.passwordResetEnabledGroupIds = @( $PasswordResetEnabledGroupIds ) # This seems like an empty value - always $Body.passwordResetEnabledGroupName = '' } if ($null -ne $SecurityQuestions) { $Body.securityQuestions = $SecurityQuestions } if ($null -ne $RegistrationConditionalAccessPolicies) { $Body.registrationConditionalAccessPolicies = $RegistrationConditionalAccessPolicies } if ($null -ne $EmailOptionAllowed) { $Body.emailOptionAllowed = $EmailOptionAllowed } if ($null -ne $MobilePhoneOptionAllowed) { $Body.mobilePhoneOptionAllowed = $MobilePhoneOptionAllowed } if ($null -ne $OfficePhoneOptionAllowed) { $Body.officePhoneOptionAllowed = $OfficePhoneOptionAllowed } if ($null -ne $SecurityQuestionsOptionAllowed) { $Body.securityQuestionsOptionAllowed = $SecurityQuestionsOptionAllowed } if ($null -ne $mobileAppNotificationOptionAllowed) { $Body.mobileAppNotificationOptionAllowed = $mobileAppNotificationOptionAllowed } if ($null -ne $mobileAppCodeOptionAllowed) { $Body.mobileAppCodeOptionAllowed = $mobileAppCodeOptionAllowed } $null = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method PUT -Body $Body } function Set-O365PasswordResetIntegration { <# .SYNOPSIS Configures password reset integration settings for Office 365. .DESCRIPTION This function updates the settings for password writeback and account unlock features in Office 365. It allows enabling or disabling the password writeback and account unlock capabilities. .PARAMETER Headers Specifies the headers for the API request. Typically includes authorization tokens. .PARAMETER PasswordWritebackSupported Indicates whether password writeback is supported. Accepts $true or $false. .PARAMETER AccountUnlockEnabled Indicates whether account unlock is enabled. Accepts $true or $false. .EXAMPLE $headers = @{Authorization = "Bearer your_token"} Set-O365PasswordResetIntegration -Headers $headers -PasswordWritebackSupported $true -AccountUnlockEnabled $true This example enables both password writeback and account unlock features. #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [nullable[bool]] $PasswordWritebackSupported, [alias('AccountUnlockSupported')][nullable[bool]] $AllowUsersTounlockWithoutReset ) $Uri = "https://main.iam.ad.ext.azure.com/api/PasswordReset/OnPremisesPasswordResetPolicies" # It seems you need to set this separatly for AccountUnlockEnabled to be picked up properly. # So we do it.. if ($null -ne $PasswordWritebackSupported) { $Body = @{ passwordWriteBackSupported = $passwordWriteBackSupported } $null = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method PUT -Body $Body } if ($null -ne $AllowUsersTounlockWithoutReset) { $Body = @{ accountUnlockEnabled = $AllowUsersTounlockWithoutReset } $null = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method PUT -Body $Body } } function Set-O365SearchIntelligenceBingConfigurations { <# .SYNOPSIS Configures the Bing Extension feature for Office 365 Search Intelligence. .DESCRIPTION This function enables or disables the Bing Extension feature for Office 365 Search Intelligence. The Bing Extension enhances search results with Bing's web search capabilities. Additionally, it allows for limiting the extension to specific groups. .PARAMETER Headers A dictionary containing the authorization headers required for the request. This includes tokens and expiration information. You can obtain these headers by using the Connect-O365Admin function. .PARAMETER ServiceEnabled A boolean value indicating whether to enable or disable the Bing Extension feature. Set to $true to enable or $false to disable. .EXAMPLE Set-O365SearchIntelligenceBingConfigurations -Headers $headers -ServiceEnabled $true This example enables the Bing Extension feature for Office 365 Search Intelligence using the provided headers. .EXAMPLE Set-O365SearchIntelligenceBingConfigurations -Headers $headers -ServiceEnabled $false This example disables the Bing Extension feature for Office 365 Search Intelligence using the provided headers. .NOTES This function requires a valid connection to Office 365 and the necessary permissions to manage Search Intelligence settings. Ensure you have the appropriate credentials and authorization before running this function. #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [bool] $ServiceEnabled ) $Uri = "https://admin.microsoft.com/admin/api/searchadminapi/configuration/update" if ($PSBoundParameters.ContainsKey('ServiceEnabled')) { $CurrentSettings = Get-O365SearchIntelligenceBingConfigurations -Headers $Headers if ($CurrentSettings) { $Body = @{ IsServiceEnabledStateChanged = $true # GUI only allows a single change to all services at once <# ServiceEnabled = $CurrentSettings.ServiceEnabled #: False People = $CurrentSettings.People #: False Groups = $CurrentSettings.Groups #: False Documents = $CurrentSettings.Documents #: False Yammer = $CurrentSettings.Yammer #: False Teams = $CurrentSettings.Teams #: False #> ServiceEnabled = $ServiceEnabled #: False People = $ServiceEnabled #: False Groups = $ServiceEnabled #: False Documents = $ServiceEnabled #: False Yammer = $ServiceEnabled #: False Teams = $ServiceEnabled #: False SaveTenantSettings = $true #: True } $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body $Output } } } function Set-O365SearchIntelligenceBingExtension { <# .SYNOPSIS Configures the Bing Extension feature for Office 365 Search Intelligence. .DESCRIPTION This function enables or disables the Bing Extension feature for Office 365 Search Intelligence. The Bing Extension enhances search results with Bing's web search capabilities. Additionally, it allows for limiting the extension to specific groups. .PARAMETER Headers A dictionary containing the authorization headers required for the request. This includes tokens and expiration information. You can obtain these headers by using the Connect-O365Admin function. .PARAMETER EnableExtension A boolean value indicating whether to enable or disable the Bing Extension feature. Set to $true to enable or $false to disable. .PARAMETER LimitGroupId An array of group IDs for which the Bing Extension should be limited. This parameter is used in conjunction with EnableExtension set to $true. .PARAMETER LimitGroupName An array of group display names for which the Bing Extension should be limited. This parameter is used in conjunction with EnableExtension set to $true. .EXAMPLE Set-O365SearchIntelligenceBingExtension -Headers $headers -EnableExtension $true This example enables the Bing Extension feature for Office 365 Search Intelligence using the provided headers. .EXAMPLE Set-O365SearchIntelligenceBingExtension -Headers $headers -EnableExtension $true -LimitGroupId "12345678-1234-1234-1234-123456789012" This example enables the Bing Extension feature and limits it to the specified group ID using the provided headers. .EXAMPLE Set-O365SearchIntelligenceBingExtension -Headers $headers -EnableExtension $true -LimitGroupName "Marketing Team" This example enables the Bing Extension feature and limits it to the group with the specified display name using the provided headers. .NOTES This function requires a valid connection to Office 365 and the necessary permissions to manage Search Intelligence settings. Ensure you have the appropriate credentials and authorization before running this function. #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [bool] $EnableExtension, [Array] $LimitGroupId, [Array] $LimitGroupName ) $Uri = "https://admin.microsoft.com/fd/bfb/api/v3/office/switch/feature" if ($EnableExtension -eq $false) { $Body = @{ Features = @(4, 7) } $null = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method DELETE -Body $Body } elseif ($EnableExtension -eq $true -and ($LimitGroupID.Count -gt 0 -or $LimitGroupName.Count -gt 0)) { # We need to first disable extension and then enable it again Set-O365SearchIntelligenceBingExtension -EnableExtension $false -Headers $Headers Start-Sleep -Seconds 1 [Array] $Groups = @( foreach ($Group in $LimitGroupID) { $GroupInformation = Get-O365Group -Id $Group -Headers $Headers if ($GroupInformation.id) { $GroupInformation } } foreach ($Group in $LimitGroupName) { $GroupInformation = Get-O365Group -DisplayName $Group -Headers $Headers if ($GroupInformation.id) { $GroupInformation } } ) $Body = @{ Features = @(4, 7 ) BingDefaultsEnabledGroupIds = @( foreach ($Group in $Groups) { $Group.id } ) BingDefaultsEnabledGroups = [ordered] @{} # @{b6cdb9c3-d660-4558-bcfd-82c14a986b56=All Users; 5f2910bc-d7a2-4529-bc66-c9d5181ab236=Graph} } foreach ($Group in $Groups) { $Body['BingDefaultsEnabledGroups'][$Group.id] = $Group.displayName } $null = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method PUT -Body $Body } elseif ($EnableExtension -eq $true) { # We need to first disable extension and then enable it again Set-O365SearchIntelligenceBingExtension -EnableExtension $false -Headers $Headers Start-Sleep -Seconds 1 $Body = @{ Features = @(4) } $null = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method PUT -Body $Body } } function Set-O365SearchIntelligenceItemInsights { <# .SYNOPSIS Configures the Item Insights feature for Office 365 Search Intelligence. .DESCRIPTION This function enables or disables Item Insights for Office 365 Search Intelligence. Item Insights provides users with relevant information about items, such as documents and emails, to enhance their productivity and collaboration. .PARAMETER Headers A dictionary containing the authorization headers required for the request. This includes tokens and expiration information. You can obtain these headers by using the Connect-O365Admin function. .PARAMETER AllowItemInsights A boolean value indicating whether to enable or disable Item Insights. Set to $true to enable or $false to disable. .PARAMETER DisableGroupName The display name of the group for which Item Insights should be disabled. This parameter is mutually exclusive with DisableGroupID. .PARAMETER DisableGroupID The ID of the group for which Item Insights should be disabled. This parameter is mutually exclusive with DisableGroupName. .EXAMPLE Set-O365SearchIntelligenceItemInsights -Headers $headers -AllowItemInsights $true This example enables Item Insights for Office 365 Search Intelligence using the provided headers. .EXAMPLE Set-O365SearchIntelligenceItemInsights -Headers $headers -AllowItemInsights $false -DisableGroupName "Marketing Team" This example disables Item Insights for the "Marketing Team" group using the provided headers. .EXAMPLE Set-O365SearchIntelligenceItemInsights -Headers $headers -AllowItemInsights $false -DisableGroupID "12345678-1234-1234-1234-123456789012" This example disables Item Insights for the group with the specified ID using the provided headers. .NOTES This function requires a valid connection to Office 365 and the necessary permissions to manage Search Intelligence settings. Ensure you have the appropriate credentials and authorization before running this function. #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [bool] $AllowItemInsights, [string] $DisableGroupName, [string] $DisableGroupID ) $Uri = "https://admin.microsoft.com/fd/configgraphprivacy/ceb371f6-8745-4876-a040-69f2d10a9d1a/settings/ItemInsights" if ($PSBoundParameters.ContainsKey('AllowItemInsights')) { if ($DisableGroupID) { $GroupInformation = Get-O365Group -Id $DisableGroupID -Headers $Headers } elseif ($DisableGroupName) { $GroupInformation = Get-O365Group -DisplayName $DisableGroupName -Headers $Headers } if ($GroupInformation.id) { $DisabledForGroup = $GroupInformation.id } else { $DisabledForGroup = $null } $Body = @{ isEnabledInOrganization = $AllowItemInsights disabledForGroup = $DisabledForGroup } $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method PATCH -Body $Body $Output } } function Set-O365SearchIntelligenceMeetingInsights { <# .SYNOPSIS Configures the Meeting Insights feature for Office 365 Search Intelligence. .DESCRIPTION This function enables or disables Meeting Insights for Office 365 Search Intelligence. Meeting Insights provides users with relevant information about meetings, such as meeting summaries and action items, to enhance their productivity and collaboration. .PARAMETER Headers A dictionary containing the authorization headers required for the request. This includes tokens and expiration information. You can obtain these headers by using the Connect-O365Admin function. .PARAMETER AllowMeetingInsights A boolean value indicating whether to enable or disable Meeting Insights. Set to $true to enable or $false to disable. .EXAMPLE Set-O365SearchIntelligenceMeetingInsights -Headers $headers -AllowMeetingInsights $true This example enables Meeting Insights for Office 365 Search Intelligence using the provided headers. .EXAMPLE Set-O365SearchIntelligenceMeetingInsights -Headers $headers -AllowMeetingInsights $false This example disables Meeting Insights for Office 365 Search Intelligence using the provided headers. .NOTES This function requires a valid connection to Office 365 and the necessary permissions to manage Search Intelligence settings. Ensure you have the appropriate credentials and authorization before running this function. #> [cmdletbinding(SupportsShouldProcess)] param( [alias('Authorization')][System.Collections.IDictionary] $Headers, [bool] $AllowMeetingInsights ) $Uri = "https://admin.microsoft.com/fd/ssms/api/v1.0/'3srecs'/Collection('meetinginsights')/Settings(Path=':',LogicalId='MeetingInsightsToggle')" if ($PSBoundParameters.ContainsKey('AllowMeetingInsights')) { $Body = @{ Payload = $AllowMeetingInsights.ToString().ToLower() } #"{`"Payload`":`"false`"}" $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method PUT -Body $Body $Output } } # Export functions and aliases as required Export-ModuleMember -Function @('Connect-O365Admin', 'ConvertFrom-JSONWebToken', 'Disconnect-O365Admin', 'Get-O365AzureADConnect', 'Get-O365AzureADConnectPTA', 'Get-O365AzureADConnectSSO', 'Get-O365AzureADRoles', 'Get-O365AzureADRolesMember', 'Get-O365AzureConditionalAccess', 'Get-O365AzureConditionalAccessClassic', 'Get-O365AzureConditionalAccessLocation', 'Get-O365AzureConditionalAccessPolicy', 'Get-O365AzureConditionalAccessTerms', 'Get-O365AzureConditionalAccessVPN', 'Get-O365AzureEnterpriseAppsGroupConsent', 'Get-O365AzureEnterpriseAppsUserConsent', 'Get-O365AzureEnterpriseAppsUserSettings', 'Get-O365AzureEnterpriseAppsUserSettingsAdmin', 'Get-O365AzureEnterpriseAppsUserSettingsPromoted', 'Get-O365AzureExternalCollaborationFlows', 'Get-O365AzureExternalCollaborationRestrictions', 'Get-O365AzureExternalCollaborationSettings', 'Get-O365AzureExternalIdentitiesEmail', 'Get-O365AzureExternalIdentitiesPolicies', 'Get-O365AzureFeatureConfiguration', 'Get-O365AzureFeaturePortal', 'Get-O365AzureGroupExpiration', 'Get-O365AzureGroupGeneral', 'Get-O365AzureGroupM365', 'Get-O365AzureGroupNamingPolicy', 'Get-O365AzureGroupSecurity', 'Get-O365AzureGroupSelfService', 'Get-O365AzureLicenses', 'Get-O365AzureMultiFactorAuthentication', 'Get-O365AzureProperties', 'Get-O365AzurePropertiesSecurity', 'Get-O365AzureTenantSKU', 'Get-O365AzureUserSettings', 'Get-O365BillingAccounts', 'Get-O365BillingInvoices', 'Get-O365BillingLicenseAutoClaim', 'Get-O365BillingLicenseRequests', 'Get-O365BillingNotifications', 'Get-O365BillingNotificationsList', 'Get-O365BillingPaymentMethods', 'Get-O365BillingProfile', 'Get-O365BillingSubscriptions', 'Get-O365ConsiergeAll', 'Get-O365CopilotPin', 'Get-O365DirectorySync', 'Get-O365DirectorySyncErrors', 'Get-O365DirectorySyncManagement', 'Get-O365Domain', 'Get-O365DomainDependencies', 'Get-O365DomainHealth', 'Get-O365DomainRecords', 'Get-O365DomainTroubleshooting', 'Get-O365Group', 'Get-O365GroupAdministrativeUnit', 'Get-O365GroupLicenses', 'Get-O365GroupMember', 'Get-O365OrgAccountLinking', 'Get-O365OrgAdoptionScore', 'Get-O365OrgAdoptionScoreConfig', 'Get-O365OrgAzureSpeechServices', 'Get-O365OrgBingDataCollection', 'Get-O365OrgBookings', 'Get-O365OrgBriefingEmail', 'Get-O365OrgCalendarSharing', 'Get-O365OrgCommunicationToUsers', 'Get-O365OrgCortana', 'Get-O365OrgCustomerLockbox', 'Get-O365OrgCustomThemes', 'Get-O365OrgDataLocation', 'Get-O365OrgDynamics365ConnectionGraph', 'Get-O365OrgDynamics365CustomerVoice', 'Get-O365OrgDynamics365SalesInsights', 'Get-O365OrgForms', 'Get-O365OrgGraphDataConnect', 'Get-O365OrgHelpdeskInformation', 'Get-O365OrgInstallationOptions', 'Get-O365OrgM365Groups', 'Get-O365OrgMicrosoftEdgeSiteLists', 'Get-O365OrgMicrosoftTeams', 'Get-O365OrgModernAuthentication', 'Get-O365OrgMyAnalytics', 'Get-O365OrgNews', 'Get-O365OrgOfficeOnTheWeb', 'Get-O365OrgOfficeProductivity', 'Get-O365OrgOrganizationInformation', 'Get-O365OrgPasswordExpirationPolicy', 'Get-O365OrgPlanner', 'Get-O365OrgPrivacyProfile', 'Get-O365OrgPrivilegedAccess', 'Get-O365OrgProject', 'Get-O365OrgReleasePreferences', 'Get-O365OrgReports', 'Get-O365OrgScripts', 'Get-O365OrgSendEmailNotification', 'Get-O365OrgSharePoint', 'Get-O365OrgSharing', 'Get-O365OrgSway', 'Get-O365OrgToDo', 'Get-O365OrgUserConsentApps', 'Get-O365OrgUserOwnedApps', 'Get-O365OrgVivaLearning', 'Get-O365OrgWhiteboard', 'Get-O365PartnerRelationship', 'Get-O365PasswordReset', 'Get-O365PasswordResetIntegration', 'Get-O365SearchIntelligenceBingConfigurations', 'Get-O365SearchIntelligenceBingExtension', 'Get-O365SearchIntelligenceItemInsights', 'Get-O365SearchIntelligenceMeetingInsights', 'Get-O365ServicePrincipal', 'Get-O365TenantID', 'Get-O365User', 'Invoke-O365Admin', 'New-O365License', 'Set-O365AzureEnterpriseAppsGroupConsent', 'Set-O365AzureEnterpriseAppsUserConsent', 'Set-O365AzureEnterpriseAppsUserSettings', 'Set-O365AzureEnterpriseAppsUserSettingsAdmin', 'Set-O365AzureExternalCollaborationRestrictions', 'Set-O365AzureExternalCollaborationSettings', 'Set-O365AzureGroupExpiration', 'Set-O365AzureGroupM365', 'Set-O365AzureGroupNamingPolicy', 'Set-O365AzureGroupSecurity', 'Set-O365AzureGroupSelfService', 'Set-O365AzureMultiFactorAuthentication', 'Set-O365AzureProperties', 'Set-O365AzurePropertiesSecurity', 'Set-O365AzureUserSettings', 'Set-O365BillingLicenseAutoClaim', 'Set-O365BillingNotifications', 'Set-O365GroupLicenses', 'Set-O365OrgAccountLinking', 'Set-O365OrgAdoptionScore', 'Set-O365OrgAzureSpeechServices', 'Set-O365OrgBingDataCollection', 'Set-O365OrgBookings', 'Set-O365OrgBriefingEmail', 'Set-O365OrgCalendarSharing', 'Set-O365OrgCommunicationToUsers', 'Set-O365OrgCortana', 'Set-O365OrgCustomerLockbox', 'Set-O365OrgDynamics365ConnectionGraph', 'Set-O365OrgDynamics365CustomerVoice', 'Set-O365OrgDynamics365SalesInsights', 'Set-O365OrgForms', 'Set-O365OrgGraphDataConnect', 'Set-O365OrgHelpdeskInformation', 'Set-O365OrgInstallationOptions', 'Set-O365OrgM365Groups', 'Set-O365OrgMicrosoftTeams', 'Set-O365OrgModernAuthentication', 'Set-O365OrgMyAnalytics', 'Set-O365OrgNews', 'Set-O365OrgOfficeOnTheWeb', 'Set-O365OrgOfficeProductivity', 'Set-O365OrgOrganizationInformation', 'Set-O365OrgPasswordExpirationPolicy', 'Set-O365OrgPlanner', 'Set-O365OrgPrivacyProfile', 'Set-O365OrgPrivilegedAccess', 'Set-O365OrgProject', 'Set-O365OrgReleasePreferences', 'Set-O365OrgReports', 'Set-O365OrgScripts', 'Set-O365OrgSendEmailNotification', 'Set-O365OrgSharePoint', 'Set-O365OrgSharing', 'Set-O365OrgSway', 'Set-O365OrgTodo', 'Set-O365OrgUserConsentApps', 'Set-O365OrgUserOwnedApps', 'Set-O365OrgVivaLearning', 'Set-O365OrgWhiteboard', 'Set-O365PasswordReset', 'Set-O365PasswordResetIntegration', 'Set-O365SearchIntelligenceBingConfigurations', 'Set-O365SearchIntelligenceBingExtension', 'Set-O365SearchIntelligenceItemInsights', 'Set-O365SearchIntelligenceMeetingInsights') -Alias @('Get-O365OrgCompanyInformation') # SIG # Begin signature block # MIItqwYJKoZIhvcNAQcCoIItnDCCLZgCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCbK2FqKF83AdIE # 99HeIaxrvzBb6axv6QQYT642aSa9tKCCJq4wggWNMIIEdaADAgECAhAOmxiO+dAt # 5+/bUOIIQBhaMA0GCSqGSIb3DQEBDAUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQK # EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNV # BAMTG0RpZ2lDZXJ0IEFzc3VyZWQgSUQgUm9vdCBDQTAeFw0yMjA4MDEwMDAwMDBa # Fw0zMTExMDkyMzU5NTlaMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2Vy # dCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lD # ZXJ0IFRydXN0ZWQgUm9vdCBHNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC # ggIBAL/mkHNo3rvkXUo8MCIwaTPswqclLskhPfKK2FnC4SmnPVirdprNrnsbhA3E # MB/zG6Q4FutWxpdtHauyefLKEdLkX9YFPFIPUh/GnhWlfr6fqVcWWVVyr2iTcMKy # unWZanMylNEQRBAu34LzB4TmdDttceItDBvuINXJIB1jKS3O7F5OyJP4IWGbNOsF # xl7sWxq868nPzaw0QF+xembud8hIqGZXV59UWI4MK7dPpzDZVu7Ke13jrclPXuU1 # 5zHL2pNe3I6PgNq2kZhAkHnDeMe2scS1ahg4AxCN2NQ3pC4FfYj1gj4QkXCrVYJB # MtfbBHMqbpEBfCFM1LyuGwN1XXhm2ToxRJozQL8I11pJpMLmqaBn3aQnvKFPObUR # WBf3JFxGj2T3wWmIdph2PVldQnaHiZdpekjw4KISG2aadMreSx7nDmOu5tTvkpI6 # nj3cAORFJYm2mkQZK37AlLTSYW3rM9nF30sEAMx9HJXDj/chsrIRt7t/8tWMcCxB # YKqxYxhElRp2Yn72gLD76GSmM9GJB+G9t+ZDpBi4pncB4Q+UDCEdslQpJYls5Q5S # UUd0viastkF13nqsX40/ybzTQRESW+UQUOsxxcpyFiIJ33xMdT9j7CFfxCBRa2+x # q4aLT8LWRV+dIPyhHsXAj6KxfgommfXkaS+YHS312amyHeUbAgMBAAGjggE6MIIB # NjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTs1+OC0nFdZEzfLmc/57qYrhwP # TzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzAOBgNVHQ8BAf8EBAMC # AYYweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdp # Y2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNv # bS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwRQYDVR0fBD4wPDA6oDigNoY0 # aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENB # LmNybDARBgNVHSAECjAIMAYGBFUdIAAwDQYJKoZIhvcNAQEMBQADggEBAHCgv0Nc # Vec4X6CjdBs9thbX979XB72arKGHLOyFXqkauyL4hxppVCLtpIh3bb0aFPQTSnov # Lbc47/T/gLn4offyct4kvFIDyE7QKt76LVbP+fT3rDB6mouyXtTP0UNEm0Mh65Zy # oUi0mcudT6cGAxN3J0TU53/oWajwvy8LpunyNDzs9wPHh6jSTEAZNUZqaVSwuKFW # juyk1T3osdz9HNj0d1pcVIxv76FQPfx2CWiEn2/K2yCNNWAcAgPLILCsWKAOQGPF # mCLBsln1VWvPJ6tsds5vIy30fnFqI2si/xK4VC0nftg62fC2h5b9W9FcrBjDTZ9z # twGpn1eqXijiuZQwggWQMIIDeKADAgECAhAFmxtXno4hMuI5B72nd3VcMA0GCSqG # SIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMx # GTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IFRy # dXN0ZWQgUm9vdCBHNDAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGIx # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 # dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBH # NDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL/mkHNo3rvkXUo8MCIw # aTPswqclLskhPfKK2FnC4SmnPVirdprNrnsbhA3EMB/zG6Q4FutWxpdtHauyefLK # EdLkX9YFPFIPUh/GnhWlfr6fqVcWWVVyr2iTcMKyunWZanMylNEQRBAu34LzB4Tm # dDttceItDBvuINXJIB1jKS3O7F5OyJP4IWGbNOsFxl7sWxq868nPzaw0QF+xembu # d8hIqGZXV59UWI4MK7dPpzDZVu7Ke13jrclPXuU15zHL2pNe3I6PgNq2kZhAkHnD # eMe2scS1ahg4AxCN2NQ3pC4FfYj1gj4QkXCrVYJBMtfbBHMqbpEBfCFM1LyuGwN1 # XXhm2ToxRJozQL8I11pJpMLmqaBn3aQnvKFPObURWBf3JFxGj2T3wWmIdph2PVld # QnaHiZdpekjw4KISG2aadMreSx7nDmOu5tTvkpI6nj3cAORFJYm2mkQZK37AlLTS # YW3rM9nF30sEAMx9HJXDj/chsrIRt7t/8tWMcCxBYKqxYxhElRp2Yn72gLD76GSm # M9GJB+G9t+ZDpBi4pncB4Q+UDCEdslQpJYls5Q5SUUd0viastkF13nqsX40/ybzT # QRESW+UQUOsxxcpyFiIJ33xMdT9j7CFfxCBRa2+xq4aLT8LWRV+dIPyhHsXAj6Kx # fgommfXkaS+YHS312amyHeUbAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD # VR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTs1+OC0nFdZEzfLmc/57qYrhwPTzANBgkq # hkiG9w0BAQwFAAOCAgEAu2HZfalsvhfEkRvDoaIAjeNkaA9Wz3eucPn9mkqZucl4 # XAwMX+TmFClWCzZJXURj4K2clhhmGyMNPXnpbWvWVPjSPMFDQK4dUPVS/JA7u5iZ # aWvHwaeoaKQn3J35J64whbn2Z006Po9ZOSJTROvIXQPK7VB6fWIhCoDIc2bRoAVg # X+iltKevqPdtNZx8WorWojiZ83iL9E3SIAveBO6Mm0eBcg3AFDLvMFkuruBx8lbk # apdvklBtlo1oepqyNhR6BvIkuQkRUNcIsbiJeoQjYUIp5aPNoiBB19GcZNnqJqGL # FNdMGbJQQXE9P01wI4YMStyB0swylIQNCAmXHE/A7msgdDDS4Dk0EIUhFQEI6FUy # 3nFJ2SgXUE3mvk3RdazQyvtBuEOlqtPDBURPLDab4vriRbgjU2wGb2dVf0a1TD9u # KFp5JtKkqGKX0h7i7UqLvBv9R0oN32dmfrJbQdA75PQ79ARj6e/CVABRoIoqyc54 # zNXqhwQYs86vSYiv85KZtrPmYQ/ShQDnUBrkG5WdGaG5nLGbsQAe79APT0JsyQq8 # 7kP6OnGlyE0mpTX9iV28hWIdMtKgK1TtmlfB2/oQzxm3i0objwG2J5VT6LaJbVu8 # aNQj6ItRolb58KaAoNYes7wPD1N1KarqE3fk3oyBIa0HEEcRrYc9B9F1vM/zZn4w # ggauMIIElqADAgECAhAHNje3JFR82Ees/ShmKl5bMA0GCSqGSIb3DQEBCwUAMGIx # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 # dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBH # NDAeFw0yMjAzMjMwMDAwMDBaFw0zNzAzMjIyMzU5NTlaMGMxCzAJBgNVBAYTAlVT # MRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjE7MDkGA1UEAxMyRGlnaUNlcnQgVHJ1 # c3RlZCBHNCBSU0E0MDk2IFNIQTI1NiBUaW1lU3RhbXBpbmcgQ0EwggIiMA0GCSqG # SIb3DQEBAQUAA4ICDwAwggIKAoICAQDGhjUGSbPBPXJJUVXHJQPE8pE3qZdRodbS # g9GeTKJtoLDMg/la9hGhRBVCX6SI82j6ffOciQt/nR+eDzMfUBMLJnOWbfhXqAJ9 # /UO0hNoR8XOxs+4rgISKIhjf69o9xBd/qxkrPkLcZ47qUT3w1lbU5ygt69OxtXXn # HwZljZQp09nsad/ZkIdGAHvbREGJ3HxqV3rwN3mfXazL6IRktFLydkf3YYMZ3V+0 # VAshaG43IbtArF+y3kp9zvU5EmfvDqVjbOSmxR3NNg1c1eYbqMFkdECnwHLFuk4f # sbVYTXn+149zk6wsOeKlSNbwsDETqVcplicu9Yemj052FVUmcJgmf6AaRyBD40Nj # gHt1biclkJg6OBGz9vae5jtb7IHeIhTZgirHkr+g3uM+onP65x9abJTyUpURK1h0 # QCirc0PO30qhHGs4xSnzyqqWc0Jon7ZGs506o9UD4L/wojzKQtwYSH8UNM/STKvv # mz3+DrhkKvp1KCRB7UK/BZxmSVJQ9FHzNklNiyDSLFc1eSuo80VgvCONWPfcYd6T # /jnA+bIwpUzX6ZhKWD7TA4j+s4/TXkt2ElGTyYwMO1uKIqjBJgj5FBASA31fI7tk # 42PgpuE+9sJ0sj8eCXbsq11GdeJgo1gJASgADoRU7s7pXcheMBK9Rp6103a50g5r # mQzSM7TNsQIDAQABo4IBXTCCAVkwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4E # FgQUuhbZbU2FL3MpdpovdYxqII+eyG8wHwYDVR0jBBgwFoAU7NfjgtJxXWRM3y5n # P+e6mK4cD08wDgYDVR0PAQH/BAQDAgGGMBMGA1UdJQQMMAoGCCsGAQUFBwMIMHcG # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln # aUNlcnRUcnVzdGVkUm9vdEc0LmNydDBDBgNVHR8EPDA6MDigNqA0hjJodHRwOi8v # Y3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNybDAgBgNV # HSAEGTAXMAgGBmeBDAEEAjALBglghkgBhv1sBwEwDQYJKoZIhvcNAQELBQADggIB # AH1ZjsCTtm+YqUQiAX5m1tghQuGwGC4QTRPPMFPOvxj7x1Bd4ksp+3CKDaopafxp # wc8dB+k+YMjYC+VcW9dth/qEICU0MWfNthKWb8RQTGIdDAiCqBa9qVbPFXONASIl # zpVpP0d3+3J0FNf/q0+KLHqrhc1DX+1gtqpPkWaeLJ7giqzl/Yy8ZCaHbJK9nXzQ # cAp876i8dU+6WvepELJd6f8oVInw1YpxdmXazPByoyP6wCeCRK6ZJxurJB4mwbfe # Kuv2nrF5mYGjVoarCkXJ38SNoOeY+/umnXKvxMfBwWpx2cYTgAnEtp/Nh4cku0+j # Sbl3ZpHxcpzpSwJSpzd+k1OsOx0ISQ+UzTl63f8lY5knLD0/a6fxZsNBzU+2QJsh # IUDQtxMkzdwdeDrknq3lNHGS1yZr5Dhzq6YBT70/O3itTK37xJV77QpfMzmHQXh6 # OOmc4d0j/R0o08f56PGYX/sr2H7yRp11LB4nLCbbbxV7HhmLNriT1ObyF5lZynDw # N7+YAN8gFk8n+2BnFqFmut1VwDophrCYoCvtlUG3OtUVmDG0YgkPCr2B2RP+v6TR # 81fZvAT6gt4y3wSJ8ADNXcL50CN/AAvkdgIm2fBldkKmKYcJRyvmfxqkhQ/8mJb2 # VVQrH4D6wPIOK+XW+6kvRBVK5xMOHds3OBqhK/bt1nz8MIIGsDCCBJigAwIBAgIQ # CK1AsmDSnEyfXs2pvZOu2TANBgkqhkiG9w0BAQwFADBiMQswCQYDVQQGEwJVUzEV # MBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29t # MSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwHhcNMjEwNDI5MDAw # MDAwWhcNMzYwNDI4MjM1OTU5WjBpMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGln # aUNlcnQsIEluYy4xQTA/BgNVBAMTOERpZ2lDZXJ0IFRydXN0ZWQgRzQgQ29kZSBT # aWduaW5nIFJTQTQwOTYgU0hBMzg0IDIwMjEgQ0ExMIICIjANBgkqhkiG9w0BAQEF # AAOCAg8AMIICCgKCAgEA1bQvQtAorXi3XdU5WRuxiEL1M4zrPYGXcMW7xIUmMJ+k # jmjYXPXrNCQH4UtP03hD9BfXHtr50tVnGlJPDqFX/IiZwZHMgQM+TXAkZLON4gh9 # NH1MgFcSa0OamfLFOx/y78tHWhOmTLMBICXzENOLsvsI8IrgnQnAZaf6mIBJNYc9 # URnokCF4RS6hnyzhGMIazMXuk0lwQjKP+8bqHPNlaJGiTUyCEUhSaN4QvRRXXegY # E2XFf7JPhSxIpFaENdb5LpyqABXRN/4aBpTCfMjqGzLmysL0p6MDDnSlrzm2q2AS # 4+jWufcx4dyt5Big2MEjR0ezoQ9uo6ttmAaDG7dqZy3SvUQakhCBj7A7CdfHmzJa # wv9qYFSLScGT7eG0XOBv6yb5jNWy+TgQ5urOkfW+0/tvk2E0XLyTRSiDNipmKF+w # c86LJiUGsoPUXPYVGUztYuBeM/Lo6OwKp7ADK5GyNnm+960IHnWmZcy740hQ83eR # Gv7bUKJGyGFYmPV8AhY8gyitOYbs1LcNU9D4R+Z1MI3sMJN2FKZbS110YU0/EpF2 # 3r9Yy3IQKUHw1cVtJnZoEUETWJrcJisB9IlNWdt4z4FKPkBHX8mBUHOFECMhWWCK # ZFTBzCEa6DgZfGYczXg4RTCZT/9jT0y7qg0IU0F8WD1Hs/q27IwyCQLMbDwMVhEC # AwEAAaOCAVkwggFVMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFGg34Ou2 # O/hfEYb7/mF7CIhl9E5CMB8GA1UdIwQYMBaAFOzX44LScV1kTN8uZz/nupiuHA9P # MA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB3BggrBgEFBQcB # AQRrMGkwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBBBggr # BgEFBQcwAoY1aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1 # c3RlZFJvb3RHNC5jcnQwQwYDVR0fBDwwOjA4oDagNIYyaHR0cDovL2NybDMuZGln # aWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZFJvb3RHNC5jcmwwHAYDVR0gBBUwEzAH # BgVngQwBAzAIBgZngQwBBAEwDQYJKoZIhvcNAQEMBQADggIBADojRD2NCHbuj7w6 # mdNW4AIapfhINPMstuZ0ZveUcrEAyq9sMCcTEp6QRJ9L/Z6jfCbVN7w6XUhtldU/ # SfQnuxaBRVD9nL22heB2fjdxyyL3WqqQz/WTauPrINHVUHmImoqKwba9oUgYftzY # gBoRGRjNYZmBVvbJ43bnxOQbX0P4PpT/djk9ntSZz0rdKOtfJqGVWEjVGv7XJz/9 # kNF2ht0csGBc8w2o7uCJob054ThO2m67Np375SFTWsPK6Wrxoj7bQ7gzyE84FJKZ # 9d3OVG3ZXQIUH0AzfAPilbLCIXVzUstG2MQ0HKKlS43Nb3Y3LIU/Gs4m6Ri+kAew # Q3+ViCCCcPDMyu/9KTVcH4k4Vfc3iosJocsL6TEa/y4ZXDlx4b6cpwoG1iZnt5Lm # Tl/eeqxJzy6kdJKt2zyknIYf48FWGysj/4+16oh7cGvmoLr9Oj9FpsToFpFSi0HA # SIRLlk2rREDjjfAVKM7t8RhWByovEMQMCGQ8M4+uKIw8y4+ICw2/O/TOHnuO77Xr # y7fwdxPm5yg/rBKupS8ibEH5glwVZsxsDsrFhsP2JjMMB0ug0wcCampAMEhLNKhR # ILutG4UI4lkNbcoFUCvqShyepf2gpx8GdOfy1lKQ/a+FSCH5Vzu0nAPthkX0tGFu # v2jiJmCG6sivqf6UHedjGzqGVnhOMIIGvDCCBKSgAwIBAgIQC65mvFq6f5WHxvnp # BOMzBDANBgkqhkiG9w0BAQsFADBjMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGln # aUNlcnQsIEluYy4xOzA5BgNVBAMTMkRpZ2lDZXJ0IFRydXN0ZWQgRzQgUlNBNDA5 # NiBTSEEyNTYgVGltZVN0YW1waW5nIENBMB4XDTI0MDkyNjAwMDAwMFoXDTM1MTEy # NTIzNTk1OVowQjELMAkGA1UEBhMCVVMxETAPBgNVBAoTCERpZ2lDZXJ0MSAwHgYD # VQQDExdEaWdpQ2VydCBUaW1lc3RhbXAgMjAyNDCCAiIwDQYJKoZIhvcNAQEBBQAD # ggIPADCCAgoCggIBAL5qc5/2lSGrljC6W23mWaO16P2RHxjEiDtqmeOlwf0KMCBD # Er4IxHRGd7+L660x5XltSVhhK64zi9CeC9B6lUdXM0s71EOcRe8+CEJp+3R2O8oo # 76EO7o5tLuslxdr9Qq82aKcpA9O//X6QE+AcaU/byaCagLD/GLoUb35SfWHh43rO # H3bpLEx7pZ7avVnpUVmPvkxT8c2a2yC0WMp8hMu60tZR0ChaV76Nhnj37DEYTX9R # eNZ8hIOYe4jl7/r419CvEYVIrH6sN00yx49boUuumF9i2T8UuKGn9966fR5X6kgX # j3o5WHhHVO+NBikDO0mlUh902wS/Eeh8F/UFaRp1z5SnROHwSJ+QQRZ1fisD8UTV # DSupWJNstVkiqLq+ISTdEjJKGjVfIcsgA4l9cbk8Smlzddh4EfvFrpVNnes4c16J # idj5XiPVdsn5n10jxmGpxoMc6iPkoaDhi6JjHd5ibfdp5uzIXp4P0wXkgNs+CO/C # acBqU0R4k+8h6gYldp4FCMgrXdKWfM4N0u25OEAuEa3JyidxW48jwBqIJqImd93N # Rxvd1aepSeNeREXAu2xUDEW8aqzFQDYmr9ZONuc2MhTMizchNULpUEoA6Vva7b1X # CB+1rxvbKmLqfY/M/SdV6mwWTyeVy5Z/JkvMFpnQy5wR14GJcv6dQ4aEKOX5AgMB # AAGjggGLMIIBhzAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/BAIwADAWBgNVHSUB # Af8EDDAKBggrBgEFBQcDCDAgBgNVHSAEGTAXMAgGBmeBDAEEAjALBglghkgBhv1s # BwEwHwYDVR0jBBgwFoAUuhbZbU2FL3MpdpovdYxqII+eyG8wHQYDVR0OBBYEFJ9X # LAN3DigVkGalY17uT5IfdqBbMFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwz # LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNFJTQTQwOTZTSEEyNTZUaW1l # U3RhbXBpbmdDQS5jcmwwgZAGCCsGAQUFBwEBBIGDMIGAMCQGCCsGAQUFBzABhhho # dHRwOi8vb2NzcC5kaWdpY2VydC5jb20wWAYIKwYBBQUHMAKGTGh0dHA6Ly9jYWNl # cnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNFJTQTQwOTZTSEEyNTZU # aW1lU3RhbXBpbmdDQS5jcnQwDQYJKoZIhvcNAQELBQADggIBAD2tHh92mVvjOIQS # R9lDkfYR25tOCB3RKE/P09x7gUsmXqt40ouRl3lj+8QioVYq3igpwrPvBmZdrlWB # b0HvqT00nFSXgmUrDKNSQqGTdpjHsPy+LaalTW0qVjvUBhcHzBMutB6HzeledbDC # zFzUy34VarPnvIWrqVogK0qM8gJhh/+qDEAIdO/KkYesLyTVOoJ4eTq7gj9UFAL1 # UruJKlTnCVaM2UeUUW/8z3fvjxhN6hdT98Vr2FYlCS7Mbb4Hv5swO+aAXxWUm3Wp # ByXtgVQxiBlTVYzqfLDbe9PpBKDBfk+rabTFDZXoUke7zPgtd7/fvWTlCs30VAGE # sshJmLbJ6ZbQ/xll/HjO9JbNVekBv2Tgem+mLptR7yIrpaidRJXrI+UzB6vAlk/8 # a1u7cIqV0yef4uaZFORNekUgQHTqddmsPCEIYQP7xGxZBIhdmm4bhYsVA6G2WgNF # YagLDBzpmk9104WQzYuVNsxyoVLObhx3RugaEGru+SojW4dHPoWrUhftNpFC5H7Q # EY7MhKRyrBe7ucykW7eaCuWBsBb4HOKRFVDcrZgdwaSIqMDiCLg4D+TPVgKx2EgE # deoHNHT9l3ZDBD+XgbF+23/zBjeCtxz+dL/9NWR6P2eZRi7zcEO1xwcdcqJsyz/J # ceENc2Sg8h3KeFUCS7tpFk7CrDqkMIIHXzCCBUegAwIBAgIQB8JSdCgUotar/iTq # F+XdLjANBgkqhkiG9w0BAQsFADBpMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGln # aUNlcnQsIEluYy4xQTA/BgNVBAMTOERpZ2lDZXJ0IFRydXN0ZWQgRzQgQ29kZSBT # aWduaW5nIFJTQTQwOTYgU0hBMzg0IDIwMjEgQ0ExMB4XDTIzMDQxNjAwMDAwMFoX # DTI2MDcwNjIzNTk1OVowZzELMAkGA1UEBhMCUEwxEjAQBgNVBAcMCU1pa2/FgsOz # dzEhMB8GA1UECgwYUHJ6ZW15c8WCYXcgS8WCeXMgRVZPVEVDMSEwHwYDVQQDDBhQ # cnplbXlzxYJhdyBLxYJ5cyBFVk9URUMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw # ggIKAoICAQCUmgeXMQtIaKaSkKvbAt8GFZJ1ywOH8SwxlTus4McyrWmVOrRBVRQA # 8ApF9FaeobwmkZxvkxQTFLHKm+8knwomEUslca8CqSOI0YwELv5EwTVEh0C/Daeh # vxo6tkmNPF9/SP1KC3c0l1vO+M7vdNVGKQIQrhxq7EG0iezBZOAiukNdGVXRYOLn # 47V3qL5PwG/ou2alJ/vifIDad81qFb+QkUh02Jo24SMjWdKDytdrMXi0235CN4Rr # W+8gjfRJ+fKKjgMImbuceCsi9Iv1a66bUc9anAemObT4mF5U/yQBgAuAo3+jVB8w # iUd87kUQO0zJCF8vq2YrVOz8OJmMX8ggIsEEUZ3CZKD0hVc3dm7cWSAw8/FNzGNP # lAaIxzXX9qeD0EgaCLRkItA3t3eQW+IAXyS/9ZnnpFUoDvQGbK+Q4/bP0ib98XLf # QpxVGRu0cCV0Ng77DIkRF+IyR1PcwVAq+OzVU3vKeo25v/rntiXCmCxiW4oHYO28 # eSQ/eIAcnii+3uKDNZrI15P7VxDrkUIc6FtiSvOhwc3AzY+vEfivUkFKRqwvSSr4 # fCrrkk7z2Qe72Zwlw2EDRVHyy0fUVGO9QMuh6E3RwnJL96ip0alcmhKABGoIqSW0 # 5nXdCUbkXmhPCTT5naQDuZ1UkAXbZPShKjbPwzdXP2b8I9nQ89VSgQIDAQABo4IC # AzCCAf8wHwYDVR0jBBgwFoAUaDfg67Y7+F8Rhvv+YXsIiGX0TkIwHQYDVR0OBBYE # FHrxaiVZuDJxxEk15bLoMuFI5233MA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAK # BggrBgEFBQcDAzCBtQYDVR0fBIGtMIGqMFOgUaBPhk1odHRwOi8vY3JsMy5kaWdp # Y2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRDb2RlU2lnbmluZ1JTQTQwOTZTSEEz # ODQyMDIxQ0ExLmNybDBToFGgT4ZNaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL0Rp # Z2lDZXJ0VHJ1c3RlZEc0Q29kZVNpZ25pbmdSU0E0MDk2U0hBMzg0MjAyMUNBMS5j # cmwwPgYDVR0gBDcwNTAzBgZngQwBBAEwKTAnBggrBgEFBQcCARYbaHR0cDovL3d3 # dy5kaWdpY2VydC5jb20vQ1BTMIGUBggrBgEFBQcBAQSBhzCBhDAkBggrBgEFBQcw # AYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMFwGCCsGAQUFBzAChlBodHRwOi8v # Y2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRDb2RlU2lnbmlu # Z1JTQTQwOTZTSEEzODQyMDIxQ0ExLmNydDAJBgNVHRMEAjAAMA0GCSqGSIb3DQEB # CwUAA4ICAQC3EeHXUPhpe31K2DL43Hfh6qkvBHyR1RlD9lVIklcRCR50ZHzoWs6E # BlTFyohvkpclVCuRdQW33tS6vtKPOucpDDv4wsA+6zkJYI8fHouW6Tqa1W47YSrc # 5AOShIcJ9+NpNbKNGih3doSlcio2mUKCX5I/ZrzJBkQpJ0kYha/pUST2CbE3JroJ # f2vQWGUiI+J3LdiPNHmhO1l+zaQkSxv0cVDETMfQGZKKRVESZ6Fg61b0djvQSx51 # 0MdbxtKMjvS3ZtAytqnQHk1ipP+Rg+M5lFHrSkUlnpGa+f3nuQhxDb7N9E8hUVev # xALTrFifg8zhslVRH5/Df/CxlMKXC7op30/AyQsOQxHW1uNx3tG1DMgizpwBasrx # h6wa7iaA+Lp07q1I92eLhrYbtw3xC2vNIGdMdN7nd76yMIjdYnAn7r38wwtaJ3KY # D0QTl77EB8u/5cCs3ShZdDdyg4K7NoJl8iEHrbqtooAHOMLiJpiL2i9Yn8kQMB6/ # Q6RMO3IUPLuycB9o6DNiwQHf6Jt5oW7P09k5NxxBEmksxwNbmZvNQ65Zn3exUAKq # G+x31Egz5IZ4U/jPzRalElEIpS0rgrVg8R8pEOhd95mEzp5WERKFyXhe6nB6bSYH # v8clLAV0iMku308rpfjMiQkqS3LLzfUJ5OHqtKKQNMLxz9z185UCszGCBlMwggZP # AgEBMH0waTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMUEw # PwYDVQQDEzhEaWdpQ2VydCBUcnVzdGVkIEc0IENvZGUgU2lnbmluZyBSU0E0MDk2 # IFNIQTM4NCAyMDIxIENBMQIQB8JSdCgUotar/iTqF+XdLjANBglghkgBZQMEAgEF # AKCBhDAYBgorBgEEAYI3AgEMMQowCKACgAChAoAAMBkGCSqGSIb3DQEJAzEMBgor # BgEEAYI3AgEEMBwGCisGAQQBgjcCAQsxDjAMBgorBgEEAYI3AgEVMC8GCSqGSIb3 # DQEJBDEiBCC9yM/aEmprTSOP32ia1ue9mJIHY7Wbx4cqFI8h2qEpMzANBgkqhkiG # 9w0BAQEFAASCAgAdbg3ThCQxJtNa9lNSl6B+SPiC9zAXondctos73V0AkmNDf5BI # owYJEL178+nOAZaCs9ZgLiRJiN857+Y+yIBBl/PVIWYVeBukMI4Xp4p3qGvN81A3 # mQbz8lkko++TkzaYbNMphN4cELZeV/48FQWwfr5W3Ijal4rKrdOPihxJpB4RO9sh # QQSJ0n0OI00L/McH1QCXbYmC1ytkzRnYfIkymb/akCSA3NG4Td7QRsb1X3LlRTGv # ZsecEaxhBlZnzGeor30I63F0VUUghbi1Awl4ck7+orgPyHALjD9bv97LfKM6xMYt # g90cyZLa0x+XkZDy4qFxwxIwTp/rLLsC59tw9kvdfEfJe8K6RP5axbcsh2ssuTVw # TYTUDB7LFwpmO130+gOSoV2jDt2UtUlbo+091aVu+gOH2rWdsi/p9fsmgrGGbRog # F7AtuOeG9SCcZlmH+Wm+3cGAcYy9VIhFlSlRB41Upby1K3/+Gbwx/UT8iJpFGS86 # RLAhaVolqP6qAyons2h9Tuxts89ovfjfV5kNifN5yeznWEzLGdeYMG1s4V4pZoJe # 7e8LDGOSmmZo+mHG9g1Rc3FcLR3ZLU8UN4njtlsCFzKQ2hrbgH8QzZU/javrCKIc # cWun0ArcB4XFmCp8KxQVZKwl+CYHHrfgcMBgNwLfHAuiwbF9i0XyRdQBfKGCAyAw # ggMcBgkqhkiG9w0BCQYxggMNMIIDCQIBATB3MGMxCzAJBgNVBAYTAlVTMRcwFQYD # VQQKEw5EaWdpQ2VydCwgSW5jLjE7MDkGA1UEAxMyRGlnaUNlcnQgVHJ1c3RlZCBH # NCBSU0E0MDk2IFNIQTI1NiBUaW1lU3RhbXBpbmcgQ0ECEAuuZrxaun+Vh8b56QTj # MwQwDQYJYIZIAWUDBAIBBQCgaTAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwG # CSqGSIb3DQEJBTEPFw0yNDEyMjIyMDAyMDdaMC8GCSqGSIb3DQEJBDEiBCDQ5yi5 # YcNGu89BWYFiKvJh3srfGQ1LxX8RlKBwU8wLTTANBgkqhkiG9w0BAQEFAASCAgAk # 9TgUduaePU3q5pnF/gYNmvW51SoIkfkWqwSdroeapWyU60hb7tb6HcuFmD1em3wb # YAa5+wX3YjS/vqirCTO1Br7zdZl8HPI+M2leWai8Quybe43kfNy8VCMSOtjGyhLb # lGbHNodVZOnwRZ2pu0b4txc5xqCoDPlYbpCnPQz4P/7kJHk1BaMQpfeKh+8hLaZ6 # m4iHwcHxu9LQs+1LYSp4Q2Q2pQJiYKO5vPknIyG43VQHfRfnCNVPRnVcMR4JT0fM # Txx9f3uXPDoMSbSt6qTPRGW0W3kJkY2Eb4UbJhqWFGr6ENNDYcjmy5/TUTuJCrMv # u0CODsSe0r2xkHtufjp1MtGIA6nXuyR9jru/3vPJvSIH+oPb8PoAE3zwKPVv2png # OJkeB8yNjPuqI2lB6OaQYfO0KVnT21yGr455R1k+r/mUekGU4MwSt+Jdr+dxRQJe # O28Y8JoO1Xy9BfwV9WhGyvsuzy79CVjicE7w9HsYelvclEwe6oh1zCMjPKHyzPy9 # 8dVTLox4bCXTpU950YY7nAGPWZZn2hQI+UJgF9G2Aih/MRCOtVRWsyJShu0/8t88 # yVHpLE19yW4aWY2Z1Jmc4sYvdDzqQq1bgTTG6nJDLdURWe+FskvU3pPZvs6Wjm0z # BwXZtzdJy5qOu20r2c2VXDZNWKtj8m1liTR3lQ1bEg== # SIG # End signature block |