Module/BackTheGraphUp.psm1
Function Get-BGUAccessToken { <# .SYNOPSIS This function is used to obtain the access token for the BackTheGraph Up commandlets, This will store a global variable with the access token for your current session. .DESCRIPTION This function is used to obtain the access token for the BackTheGraph Up commandlets, This will store a global variable with the access token for your current session. This module requires the Connect-AZAD_Token module to be installed, if this is not already installed, It will install it for you. .EXAMPLE PS C:\> Get-BGUAccessToken This will connect you to the tenant your account is associated with. .EXAMPLE PS C:\> Get-BGUAccessToken -TenantID <TenantID> This will allow you connect to another tenant even as a guest account as long as you have the privileges. .EXAMPLE PS C:\> Get-BGUAccessToken -DelegateID <ClientApplicationID> This will be required to manage conditional access modules, as these require additional permissions not granted to the Default Powershell Module. .EXAMPLE PS C:\> Get-BGUAccessToken -TenantID <TenantID> -ClientID <ClientApplicationID> -ClientSecret <ClientSecret> This will connect you to a tenant without been prompted to login. .INPUTS -TenantID : Used to connect to another Tenant -ClientID : Used to connect to the Graph API using a Client ID and Secret, Also requires TenantID (AKA. Application Access) -ClientSecret : See ClientID -DelegateID : This will be required to manage conditional access modules, as these require additional permissions not granted to the Default Powershell Module. .OUTPUTS $BGUAccessToken : This contains all of the information used in other modules. .NOTES #> [CmdletBinding()] param ( [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [string] $ClientID, [string] $ClientSecret, #Your Azure Tenent ID [string] $TenantId, [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion", [string] $DelegateID ) begin { $RequireMod = Get-Module -Name "Connect-AzAD_Token" -ListAvailable if (!($RequireMod)) { try { Write-Host -ForegroundColor Cyan "Attempting to Install the Connect-AzADToken Powershell module..." Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force -ErrorAction Stop | Out-Null Install-Module "Connect-AzAD_token" -Force -ErrorAction Stop } catch { Throw "Failed to install the AzureAD PowerShell Module" } } Import-Module Connect-AzAD_Token $ConnectParams = @{} IF ($ClientID) { $ConnectParams.Add('ClientID', $ClientID) } IF ($ClientSecret) { $ConnectParams.Add('ClientSecret', $ClientSecret) } IF ($DelegateID) { $ConnectParams.Add('DelegateID', $DelegateID) } IF ($TenantId) { $ConnectParams.Add('Tenant', $TenantId) } ELSE { $TenantID = $UserInfo.TenantID } } #Process The Function Process { try { $global:BGUAccessToken = Connect-AzAD_Token @ConnectParams } catch { $Error[0] throw "Failed to obtain access token" } } } #region AdminTemplates Function Get-AdminTemplates { <# .SYNOPSIS This function is used to get Administrative Template policies from the GraphAPI Associated with your connected tenant. .DESCRIPTION This function is used to get Administrative Template policies from the GraphAPI Associated with your connected tenant. It is possible to filter these by using -Type FilterQuery -FilterID <policyID>, you can also user Where-Object to filter these. .EXAMPLE PS C:\> Get-AdminTemplates This will return all of the policies within your connected tenant .EXAMPLE PS C:\> Get-AdminTemplates -Type FilterQuery -FilterID <PolicyID> This will return the single policy for the ID you specify .INPUTS -Type : Used when you want to specify if you want to Filter the ID. -FilterID : The ID of the Policy .OUTPUTS Sample: createdDateTime : 2020-11-19T09:40:16.901865Z displayName : Prod - AdminTemplate description : roleScopeTagIds : {0} id : 7f0bb273-xxx-xxx-xx-823aff445xxx lastModifiedDateTime : 2020-11-19T09:40:17.4799505Z .NOTES #> [CmdletBinding()] param ( [ValidateSet('All', 'FilterQuery')] $Type, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion" ) DynamicParam { #If the Import Param is used, Create the File Param switch ($Type) { FilterQuery { $FAttrib = New-Object System.Management.Automation.ParameterAttribute $FAttrib.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom FileAttribute attribute $attributeCollection.Add($FAttrib) #add our paramater specifying the attribute collection $FilterID = New-Object System.Management.Automation.RuntimeDefinedParameter('FilterID', [string], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('FilterID', $FilterID) return $paramDictionary } } } begin { IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } $GraphHeader = @{Authorization = "Bearer $($BGUAccessToken.AccessToken)" } } #Process The Function Process { try { $GraphParams = @{ Method = "GET" URI = "$GraphURI/deviceManagement/groupPolicyConfigurations" Headers = $GraphHeader } $GraphRequest = Invoke-RestMethod @GraphParams -ErrorAction Stop $All_GraphRequest = @() $All_GraphRequest += $GraphRequest while ($GraphRequest.'@odata.nextLink') { $GraphRequest_NextLink = @{ Method = "GET" URI = $GraphRequest.'@odata.nextLink' Headers = $GraphHeader ContentType = "application/JSON" } $GraphRequest = Invoke-RestMethod @GraphRequest_NextLink -ErrorAction Stop $All_GraphRequest += $GraphRequest } } catch { $Error[0] Throw "The Microsoft Graph Query Failed," } Switch ($Type) { Default { $All_GraphRequest | Select-Object -ExpandProperty Value } FilterQuery { $All_GraphRequest | Select-Object -ExpandProperty Value | Where-Object id -Match $($PSBoundParameters.FilterID) } } } } Function Import-AdminTemplate { [CmdletBinding()] param ( [ValidateSet('Object', 'File')] $Type, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion" ) DynamicParam { switch ($Type) { File { #If the Import Param is used, Create the File Param $FileAttribute = New-Object System.Management.Automation.ParameterAttribute $FileAttribute.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom FileAttribute attribute $attributeCollection.Add($FileAttribute) #add our paramater specifying the attribute collection $File = New-Object System.Management.Automation.RuntimeDefinedParameter('File', [string], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('File', $File) return $paramDictionary } Object { $ObjectAttrib = New-Object System.Management.Automation.ParameterAttribute $ObjectAttrib.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom ObjectAttrib attribute $attributeCollection.Add($ObjectAttrib) #add our paramater specifying the attribute collection $ImportObject = New-Object System.Management.Automation.RuntimeDefinedParameter('ImportObject', [Object], $attributeCollection) $ImportObject_Settings = New-Object System.Management.Automation.RuntimeDefinedParameter('ImportObject_Settings', [Object], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('ImportObject', $ImportObject) $paramDictionary.Add('ImportObject_Settings', $ImportObject_Settings) return $paramDictionary } } } begin { #If the File Param is used, Test the Path to make sure its accessible, If not throw an error. If it does exist set the Import_File Param to the AttributeValue IF ($PSBoundParameters.File) { IF (-not (Test-Path -Path $PSBoundParameters.File)) { Throw "Unable to locate $PSBoundParameters.File" } else { $Import_File = $PSBoundParameters.File } } IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } $GraphHeader = @{Authorization = "Bearer $($BGUAccessToken.AccessToken)" } } #Process The Function Process { switch ($Type) { File { $File_Info = Get-Item $Import_File | Select-Object -Property * $ImportSettingsFile = Join-Path -Path $File_Info.DirectoryName -ChildPath ($File_Info.BaseName + "_settings.json") if (Test-Path -Path $ImportSettingsFile) { $Settings = (ConvertFrom-Json -InputObject (Get-Content $ImportSettingsFile -Raw)) } $BasePolicyJSON = Get-Content $Import_File | ConvertFrom-Json | Select-Object -Property * -ExcludeProperty Version, LastModifiedTime, CreatedDateTime, id, supportsScopeTags | ConvertTo-Json -Depth 10 } Object { $BasePolicyJSON = $PSBoundParameters.ImportObject | Select-Object -Property * -ExcludeProperty Version, LastModifiedTime, CreatedDateTime, id, supportsScopeTags, lastModifiedDateTime | ConvertTo-Json -Depth 10 $Settings = $PSBoundParameters.ImportObject_Settings } } $GraphBasePolicyImportParams = @{ Method = "POST" URI = "$GraphURI/deviceManagement/groupPolicyConfigurations" BODY = $BasePolicyJSON Headers = $GraphHeader CONTENTTYPE = "application/Json" } $BasePolicyImport_Request = Invoke-RestMethod @GraphBasePolicyImportParams IF ($BasePolicyImport_Request) { foreach ($Setting in $Settings) { $Setting.psobject.Properties.Remove('presentation') $Setting.psobject.Properties.Remove('ID') $Setting.psobject.Properties.Remove('lastModifiedDateTime') $Setting.psobject.Properties.Remove('createdDateTime') IF ($Setting.presentationValues) { $CurrentSettings = $Setting.presentationValues | Select-Object * -ExcludeProperty presentation, id, lastmodifieddatetime, createddatetime $Setting.presentationValues = @() $Setting.presentationValues += $CurrentSettings } $GraphImportParams = @{ Method = "POST" URI = "$GraphURI/deviceManagement/groupPolicyConfigurations/$($BasePolicyImport_Request.id)/definitionValues" BODY = ($Setting | ConvertTo-Json -Depth 10) Headers = $GraphHeader CONTENTTYPE = "application/Json" } Invoke-RestMethod @GraphImportParams } } } } function Get-AdminTemplate_Settings { <# .SYNOPSIS This function is used to get Administrative Template policy settings from the GraphAPI Associated with your connected tenant. .DESCRIPTION This function is used to get Administrative Template policy settings from the GraphAPI Associated with your connected tenant. This function accepts the Object input from Get-AdminTemplates .EXAMPLE PS C:\> Get-AdminTemplates_Settings -InputObject (Get-AdminTemplates -Type FilterQuery -FilterID <PolicyID>) This will return all of the policy settings for that AdminTemplate .INPUTS -InputObject : The object output of Get-AdminTemplates .OUTPUTS Sample: Name Value ---- ----- definition@odata.bind https://graph.microsoft.com/beta/deviceManagement/groupPolicyDefinitions('43bd9826-a322-4562-ad44-3541e19bdb37') enabled True definition@odata.bind https://graph.microsoft.com/beta/deviceManagement/groupPolicyDefinitions('e44011cd-6e22-4068-a722-4f3aa7d50423') enabled True .NOTES #> param( [Parameter(Mandatory = $true)] $InputObject, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion" ) begin { IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } $GraphHeader = @{Authorization = "Bearer $($BGUAccessToken.AccessToken)" } } Process { $adm_settings = @() # Get all policies set for the profile $GraphDefinitionValuesParam = @{ METHOD = "GET" URI = "$GraphURI/deviceManagement/groupPolicyConfigurations/$($InputObject.id)/definitionValues?`$expand=definition" HEADERS = $GraphHeader } $Definition_Values = Invoke-RestMethod @GraphDefinitionValuesParam #For Each definition value, Get the presentation value with its settings foreach ($Def in $Definition_Values.value) { # Get presentation values for the passed in object $GraphPresentationValuesParams = @{ METHOD = "GET" URI = "$GraphURI/deviceManagement/groupPolicyConfigurations/$($InputObject.id)/definitionValues/$($Def.id)/presentationValues?`$expand=presentation" HEADERS = $GraphHeader } $presnetation_values = Invoke-RestMethod @GraphPresentationValuesParams $adm_obj = @{ "enabled" = $Def.enabled "definition@odata.bind" = "$($GraphURI)/deviceManagement/groupPolicyDefinitions('$($Def.definition.id)')" } #If presentation_Values is not blank, Get the settings if ($presnetation_values.value) { # Policy presentation values $adm_obj.presentationValues = @() $presnetation = $null foreach ($presentation in $presnetation_values.value) { $presentation | Add-Member -MemberType NoteProperty -Name "presentation@odata.bind" -Value "$($GraphURI)/deviceManagement/groupPolicyDefinitions('$($Def.definition.id)')/presentations('$($presentation.presentation.id)')" $adm_obj.presentationValues += $presentation } } $adm_settings += $adm_obj } $adm_settings } } function Export-AdminTemplate { param( [Parameter(Mandatory = $True)] $PolicyID, [ValidateSet('Object', 'File')] [Parameter(Mandatory = $True)] $Type, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion" ) DynamicParam { #If the Import Param is used, Create the File Param switch ($Type) { File { $FileAttribute = New-Object System.Management.Automation.ParameterAttribute $FileAttribute.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom FileAttribute attribute $attributeCollection.Add($FileAttribute) #add our paramater specifying the attribute collection $ExportLocation = New-Object System.Management.Automation.RuntimeDefinedParameter('ExportLocation', [string], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('ExportLocation', $ExportLocation) return $paramDictionary } } } begin { IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } $GraphHeader = @{Authorization = "Bearer $($BGUAccessToken.AccessToken)" } } Process { $GraphObjectParams = @{ METHOD = "GET" URI = "$GraphURI/deviceManagement/groupPolicyConfigurations/$($PolicyID)" HEADERS = $GraphHeader } $export_obj = Invoke-RestMethod @GraphObjectParams if ($export_obj) { switch ($Type) { Object { $export_obj } File { # Export The Base Admin Template ConvertTo-Json $export_obj -Depth 10 | Out-File "$ExportLocation\$(($export_obj.displayName)).json" -Encoding ascii -Force # Export the settings from the Admin Template $adm_settings = Get-AdminTemplate_Settings -InputObject $export_obj ConvertTo-Json $adm_settings -Depth 10 | Out-File "$ExportLocation\$($export_obj.displayName)_Settings.json" -Encoding ascii -Force } } } } } function Copy-AdminTemplate { param( [string] [Parameter(Mandatory = $True)] $PolicyID, [Parameter(Mandatory = $True)] [ValidateSet('Copy', 'Test', 'PreProd', 'Dev', 'Prod', 'Pilot', 'Custom')] $Prefix, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion" ) DynamicParam { #If the Import Param is used, Create the File Param switch ($Prefix) { Custom { $CustomAttrib = New-Object System.Management.Automation.ParameterAttribute $CustomAttrib.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom CustomAttrib attribute $attributeCollection.Add($CustomAttrib) #add our paramater specifying the attribute collection $CustomPrefix = New-Object System.Management.Automation.RuntimeDefinedParameter('CustomPrefix', [string], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('CustomPrefix', $CustomPrefix) return $paramDictionary } } } begin { IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } switch ($Prefix) { Custom { $PolicyPrefix = $PSBoundParameters.CustomPrefix.ToUpper() } Default { $PolicyPrefix = $Prefix.ToUpper() } } } process { Write-Output "Object iD: $($PolicyID)" $BaseObject = Export-AdminTemplate -Type Object $PolicyID $BaseObject.displayName = "$PolicyPrefix-$($BaseObject.displayName)" $BaseObject_Settings = Get-AdminTemplate_Settings -InputObject $BaseObject Import-AdminTemplate -Type Object -ImportObject $BaseObject -ImportObject_Settings $BaseObject_Settings } } #endregion Admin Templates #region Scripts function Invoke-Encoder { param ( [Parameter(Mandatory = $true)] [ValidateSet('Encode', 'Decode')] $Type, [Parameter(Mandatory = $true)] [string] $Value ) switch ($Type) { Encode { [Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($Value)) } Decode { [System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String($Value)) } } } Function Get-IntuneScript { <# .SYNOPSIS This function is used to get Intune Based Scripts from the GraphAPI Associated with your connected tenant. .DESCRIPTION This function is used to get Intune Based Scripts from the GraphAPI Associated with your connected tenant. It is possible to filter these by using -Type FilterQuery -FilterID <policyID>, you can also user Where-Object to filter these. .EXAMPLE PS C:\> Get-IntuneScript This will return all of the scripts within your connected tenant .EXAMPLE PS C:\> Get-IntuneScripts -Type FilterQuery -FilterID <PolicyID> This will return the single script for the ID you specify .INPUTS -Type : Used when you want to specify if you want to Filter the ID. -FilterID : The ID of the Policy .OUTPUTS Sample: enforceSignatureCheck : False runAs32Bit : False id : 5ab5bc74-xxxx-xxxx-xxxx-64e12xxxabcb displayName : ScriptDisplay description : Updated 04/23/2021 08:26:41 Updated 04/23/2021 08:28:51 scriptContent : createdDateTime : 2021-04-20T14:00:12.9934699Z lastModifiedDateTime : 2021-04-23T07:28:51.4886844Z runAsAccount : system fileName : ScriptDisplay.ps1 roleScopeTagIds : {0} .NOTES #> [CmdletBinding()] param ( [ValidateSet('All', 'FilterQuery')] $Type, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion" ) DynamicParam { #If the Import Param is used, Create the File Param switch ($Type) { FilterQuery { $FAttrib = New-Object System.Management.Automation.ParameterAttribute $FAttrib.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom FileAttribute attribute $attributeCollection.Add($FAttrib) #add our paramater specifying the attribute collection $FilterID = New-Object System.Management.Automation.RuntimeDefinedParameter('FilterID', [string], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('FilterID', $FilterID) return $paramDictionary } } } begin { IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } $GraphHeader = @{Authorization = "Bearer $($BGUAccessToken.AccessToken)" } } #Process The Function Process { try { $GraphParams = @{ Method = "GET" URI = "$GraphURI/deviceManagement/deviceManagementScripts" Headers = $GraphHeader } $GraphRequest = Invoke-RestMethod @GraphParams -ErrorAction Stop $All_GraphRequest = @() $All_GraphRequest += $GraphRequest while ($GraphRequest.'@odata.nextLink') { $GraphRequest_NextLink = @{ Method = "GET" URI = $GraphRequest.'@odata.nextLink' Headers = $GraphHeader ContentType = "application/JSON" } $GraphRequest = Invoke-RestMethod @GraphRequest_NextLink -ErrorAction Stop $All_GraphRequest += $GraphRequest } } catch { $Error[0] Throw "The Microsoft Graph Query Failed," } Switch ($Type) { Default { $All_GraphRequest | Select-Object -ExpandProperty Value } FilterQuery { $All_GraphRequest | Select-Object -ExpandProperty Value | Where-Object id -Match $($PSBoundParameters.FilterID) } } } } Function Import-IntuneScript { [CmdletBinding()] param ( [ValidateSet('Object', 'File')] $Type, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion" ) DynamicParam { switch ($Type) { File { #If the Import Param is used, Create the File Param $FileAttribute = New-Object System.Management.Automation.ParameterAttribute $FileAttribute.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom FileAttribute attribute $attributeCollection.Add($FileAttribute) #add our paramater specifying the attribute collection $File = New-Object System.Management.Automation.RuntimeDefinedParameter('File', [string], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('File', $File) return $paramDictionary } Object { $ObjectAttrib = New-Object System.Management.Automation.ParameterAttribute $ObjectAttrib.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom ObjectAttrib attribute $attributeCollection.Add($ObjectAttrib) #add our paramater specifying the attribute collection $ImportObject = New-Object System.Management.Automation.RuntimeDefinedParameter('ImportObject', [Object], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('ImportObject', $ImportObject) return $paramDictionary } } } begin { #If the File Param is used, Test the Path to make sure its accessible, If not throw an error. If it does exist set the JSONImport Param to the AttributeValue IF ($PSBoundParameters.File) { IF (-not (Test-Path -Path $PSBoundParameters.File)) { Throw "Unable to locate $PSBoundParameters.File" } else { $Import_File = $PSBoundParameters.File } } IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } $GraphHeader = @{Authorization = "Bearer $($BGUAccessToken.AccessToken)" } } #Process The Function Process { switch ($Type) { File { $File_Info = Get-Item $Import_File | Select-Object -Property * $ImportScript = Join-Path -Path $File_Info.DirectoryName -ChildPath ($File_Info.BaseName + ".ps1") $ImportObject = Get-Content $Import_File | ConvertFrom-Json | Select-Object -Property * -ExcludeProperty Version, LastModifiedTime, CreatedDateTime, id, supportsScopeTags if (Test-Path -Path $ImportScript) { $ImportObject.scriptContent = (Invoke-Encoder -Type Encode (Get-Content $ImportScript -Raw)) } $ImportJSON = $ImportObject | ConvertTo-Json -Depth 10 } Object { $ImportJSON = $PSBoundParameters.ImportObject | Select-Object -Property * -ExcludeProperty Version, LastModifiedTime, CreatedDateTime, id, supportsScopeTags, lastModifiedDateTime | ConvertTo-Json -Depth 10 } } $GraphImportParams = @{ Method = "POST" URI = "$GraphURI/deviceManagement/deviceManagementScripts" BODY = $ImportJSON Headers = $GraphHeader CONTENTTYPE = "application/Json" } Invoke-RestMethod @GraphImportParams } } function Export-IntuneScript { param( [Parameter(Mandatory = $True)] $PolicyID, [ValidateSet('Object', 'File', 'ScriptOnly')] [Parameter(Mandatory = $True)] $Type, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion" ) DynamicParam { #If the Import Param is used, Create the File Param switch ($Type) { File { $FileAttribute = New-Object System.Management.Automation.ParameterAttribute $FileAttribute.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom FileAttribute attribute $attributeCollection.Add($FileAttribute) #add our paramater specifying the attribute collection $ExportLocation = New-Object System.Management.Automation.RuntimeDefinedParameter('ExportLocation', [string], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('ExportLocation', $ExportLocation) return $paramDictionary } ScriptOnly { $FileAttribute = New-Object System.Management.Automation.ParameterAttribute $FileAttribute.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom FileAttribute attribute $attributeCollection.Add($FileAttribute) #add our paramater specifying the attribute collection $ExportLocation = New-Object System.Management.Automation.RuntimeDefinedParameter('ExportLocation', [string], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('ExportLocation', $ExportLocation) return $paramDictionary } } } begin { IF ($PSBoundParameters.ExportLocation) { $ExportLocation = $PSBoundParameters.ExportLocation } IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } $GraphHeader = @{Authorization = "Bearer $($BGUAccessToken.AccessToken)" } } Process { $GraphObjectParams = @{ METHOD = "GET" URI = "$GraphURI/deviceManagement/deviceManagementScripts/$($PolicyID)" HEADERS = $GraphHeader } $export_obj = Invoke-RestMethod @GraphObjectParams if ($export_obj) { switch ($Type) { Object { $export_obj } File { # Export The Base Admin Template ConvertTo-Json $export_obj -Depth 10 | Out-File "$ExportLocation\$(($export_obj.displayName)).json" -Encoding ascii -Force Invoke-Encoder -Type Decode -Value $export_obj.ScriptContent | Out-File "$ExportLocation\$(($export_obj.displayName)).PS1" -Encoding ascii -Force } ScriptOnly { Invoke-Encoder -Type Decode -Value $export_obj.ScriptContent | Out-File "$ExportLocation\$(($export_obj.displayName)).PS1" -Encoding ascii -Force } } } } } function Copy-IntuneScript { param( [string] [Parameter(Mandatory = $True)] $PolicyID, [Parameter(Mandatory = $True)] [ValidateSet('Copy', 'Test', 'PreProd', 'Dev', 'Prod', 'Pilot', 'Custom')] $Prefix, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion" ) DynamicParam { #If the Import Param is used, Create the File Param switch ($Prefix) { Custom { $CustomAttrib = New-Object System.Management.Automation.ParameterAttribute $CustomAttrib.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom CustomAttrib attribute $attributeCollection.Add($CustomAttrib) #add our paramater specifying the attribute collection $CustomPrefix = New-Object System.Management.Automation.RuntimeDefinedParameter('CustomPrefix', [string], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('CustomPrefix', $CustomPrefix) return $paramDictionary } } } begin { IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } switch ($Prefix) { Custom { $PolicyPrefix = $PSBoundParameters.CustomPrefix.ToUpper() } Default { $PolicyPrefix = $Prefix.ToUpper() } } } process { Write-Output "Object iD: $($PolicyID)" $BaseObject = Export-IntuneScript -Type Object $PolicyID $BaseObject.displayName = "$PolicyPrefix-$($BaseObject.displayName)" Import-IntuneScript -Type Object -ImportObject $BaseObject } } function Update-IntuneScript { param( [string] [Parameter(Mandatory = $True)] $PolicyID, [Parameter(Mandatory = $True)] [ValidateSet('Object', 'File')] $Type, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion", [switch] $DoNotAppendDescription ) DynamicParam { switch ($Type) { File { #If the Import Param is used, Create the File Param $PSAttrib = New-Object System.Management.Automation.ParameterAttribute $PSAttrib.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom PSAttrib attribute $attributeCollection.Add($PSAttrib) #add our paramater specifying the attribute collection $ScriptFile = New-Object System.Management.Automation.RuntimeDefinedParameter('ScriptFile', [string], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('ScriptFile', $ScriptFile) return $paramDictionary } Object { $ObjectAttrib = New-Object System.Management.Automation.ParameterAttribute $ObjectAttrib.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom ObjectAttrib attribute $attributeCollection.Add($ObjectAttrib) #add our paramater specifying the attribute collection $ScriptObject = New-Object System.Management.Automation.RuntimeDefinedParameter('ScriptObject', [Object], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('ScriptObject', $ScriptObject) return $paramDictionary } } } begin { IF ($PSBoundParameters.ScriptFile) { IF (-not (Test-Path -Path $PSBoundParameters.ScriptFile)) { Throw "Unable to locate $PSBoundParameters.ScriptFile" } else { $ScriptImport = $PSBoundParameters.ScriptFile } } IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } $GraphHeader = @{Authorization = "Bearer $($BGUAccessToken.AccessToken)" } } Process { Write-Output "Object iD: $($PolicyID)" $Policy = Get-IntuneScript -Type FilterQuery -FilterID $PolicyID switch ($Type) { File { $Policy.ScriptContent = Invoke-Encoder -Type Encode -Value (Get-Content $ScriptImport -Raw) } Object { $Policy.ScriptContent = Invoke-Encoder -Type Encode -Value $ScriptObject } } switch ($DoNotAppendDescription) { false { if ([string]::IsNullOrEmpty($Policy.description)) { $NewDescription = "Updated $(Get-Date)" } else { $CurrentDescription = $Policy.description $NewDescription = "$CurrentDescription `nUpdated $(Get-Date)" } $Policy.description = $NewDescription } } $GraphImportParams = @{ Method = "PATCH" URI = "$GraphURI/deviceManagement/deviceManagementScripts/$PolicyID" BODY = ($Policy | Select-Object -Property * -ExcludeProperty Version, LastModifiedDateTime, CreatedDateTime, id, supportsScopeTags | ConvertTo-Json -Depth 10) Headers = $GraphHeader CONTENTTYPE = "application/Json" } Invoke-RestMethod @GraphImportParams } } function Edit-IntuneScript { param( [Parameter(Mandatory = $True)] $PolicyID, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion", [switch] $DoNotAppendDescription ) DynamicParam { } begin { IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } $GraphHeader = @{Authorization = "Bearer $($BGUAccessToken.AccessToken)" } } Process { $GraphObjectParams = @{ METHOD = "GET" URI = "$GraphURI/deviceManagement/deviceManagementScripts/$($PolicyID)" HEADERS = $GraphHeader } $export_obj = Invoke-RestMethod @GraphObjectParams if ($export_obj) { $TempFile = "$env:TEMP\$(($export_obj.displayName)).PS1" Invoke-Encoder -Type Decode -Value $export_obj.ScriptContent | Out-File $TempFile -Encoding ascii -Force Start-Job -Name "EditIntuneScript_$($export_obj.displayname)" -ScriptBlock { param($TempFile) Start-Process notepad -ArgumentList "$TempFile" -wait } -ArgumentList $TempFile | Wait-Job | Out-Null #Start-Process "NotePad.exe" -ArgumentList "$TempFile" -Wait switch ($DoNotAppendDescription) { false { Update-IntuneScript -PolicyID $PolicyID -Type File -ScriptFile $TempFile } true { Update-IntuneScript -PolicyID $PolicyID -Type File -ScriptFile $TempFile -DoNotAppendDescription } } Remove-Item -Path $TempFile -Force } } } #endregion Scripts #region AppProtection Policies Function Get-AppProtectionPolicies { <# .SYNOPSIS This function is used to get App Protection policies from the GraphAPI Associated with your connected tenant. .DESCRIPTION This function is used to get App Protection policies from the GraphAPI Associated with your connected tenant. It is possible to filter these by using -Type FilterQuery -FilterID <policyID>, you can also user Where-Object to filter these. .EXAMPLE PS C:\> Get-AppProtectionPolicies This will return all of the policies within your connected tenant .EXAMPLE PS C:\> Get-AppProtectionPolicies -Type FilterQuery -FilterID <PolicyID> This will return the single policy for the ID you specify .INPUTS -Type : Used when you want to specify if you want to Filter the ID. -FilterID : The ID of the Policy .OUTPUTS Sample: @odata.type : #microsoft.graph.windowsInformationProtectionPolicy displayName : AppProtection Policy Name description : createdDateTime : 2021-04-13T06:58:28.6163181Z lastModifiedDateTime : 2021-04-13T06:58:28.6163181Z roleScopeTagIds : {0} id : W_24415669-xxxx-xxxx-xxxx-5b4598e23da4 version : 0.0 enforcementLevel : encryptAuditAndPrompt enterpriseDomain : YourDomain.co.uk protectionUnderLockConfigRequired : False dataRecoveryCertificate : revokeOnUnenrollDisabled : False rightsManagementServicesTemplateId : azureRightsManagementServicesAllowed : False iconsVisible : False enterpriseIPRangesAreAuthoritative : False enterpriseProxyServersAreAuthoritative : False indexingEncryptedStoresOrItemsBlocked : False isAssigned : False revokeOnMdmHandoffDisabled : False mdmEnrollmentUrl : https://enrollment.manage.microsoft.com/enrollmentserver/discovery.svc windowsHelloForBusinessBlocked : False pinMinimumLength : 4 pinUppercaseLetters : notAllow pinLowercaseLetters : notAllow pinSpecialCharacters : notAllow pinExpirationDays : 0 numberOfPastPinsRemembered : 0 passwordMaximumAttemptCount : 0 minutesOfInactivityBeforeDeviceLock : 0 daysWithoutContactBeforeUnenroll : 90 enterpriseProtectedDomainNames : {} protectedApps : {} exemptApps : {} enterpriseNetworkDomainNames : {} enterpriseProxiedDomains : {} enterpriseIPRanges : {} enterpriseProxyServers : {} enterpriseInternalProxyServers : {} neutralDomainResources : {} smbAutoEncryptedFileExtensions : {} .NOTES #> [CmdletBinding()] param ( [ValidateSet('All', 'FilterQuery')] $Type, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion" ) DynamicParam { #If the Import Param is used, Create the File Param switch ($Type) { FilterQuery { $FAttrib = New-Object System.Management.Automation.ParameterAttribute $FAttrib.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom FileAttribute attribute $attributeCollection.Add($FAttrib) #add our paramater specifying the attribute collection $FilterID = New-Object System.Management.Automation.RuntimeDefinedParameter('FilterID', [string], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('FilterID', $FilterID) return $paramDictionary } } } begin { IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } $GraphHeader = @{Authorization = "Bearer $($BGUAccessToken.AccessToken)" } } #Process The Function Process { try { $GraphParams = @{ Method = "GET" URI = "$GraphURI/deviceAppManagement/managedAppPolicies" Headers = $GraphHeader } $GraphRequest = Invoke-RestMethod @GraphParams -ErrorAction Stop $All_GraphRequest = @() $All_GraphRequest += $GraphRequest while ($GraphRequest.'@odata.nextLink') { $GraphRequest_NextLink = @{ Method = "GET" URI = $GraphRequest.'@odata.nextLink' Headers = $GraphHeader ContentType = "application/JSON" } $GraphRequest = Invoke-RestMethod @GraphRequest_NextLink -ErrorAction Stop $All_GraphRequest += $GraphRequest } } catch { $Error[0] Throw "The Microsoft Graph Query Failed," } Switch ($Type) { Default { $All_GraphRequest | Select-Object -ExpandProperty Value } FilterQuery { $All_GraphRequest | Select-Object -ExpandProperty Value | Where-Object id -Match $($PSBoundParameters.FilterID) } } } } Function Import-AppProtectionPolicies { [CmdletBinding()] param ( [ValidateSet('Object', 'File')] $Type, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion" ) DynamicParam { switch ($Type) { File { #If the Import Param is used, Create the File Param $FileAttribute = New-Object System.Management.Automation.ParameterAttribute $FileAttribute.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom FileAttribute attribute $attributeCollection.Add($FileAttribute) #add our paramater specifying the attribute collection $File = New-Object System.Management.Automation.RuntimeDefinedParameter('File', [string], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('File', $File) return $paramDictionary } Object { $ObjectAttrib = New-Object System.Management.Automation.ParameterAttribute $ObjectAttrib.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom ObjectAttrib attribute $attributeCollection.Add($ObjectAttrib) #add our paramater specifying the attribute collection $ImportObject = New-Object System.Management.Automation.RuntimeDefinedParameter('ImportObject', [Object], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('ImportObject', $ImportObject) return $paramDictionary } } } begin { #If the File Param is used, Test the Path to make sure its accessible, If not throw an error. If it does exist set the JSONImport Param to the AttributeValue IF ($PSBoundParameters.File) { IF (-not (Test-Path -Path $PSBoundParameters.File)) { Throw "Unable to locate $PSBoundParameters.File" } else { $JSONImport = $PSBoundParameters.File } } IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } $GraphHeader = @{Authorization = "Bearer $($BGUAccessToken.AccessToken)" } } #Process The Function Process { switch ($Type) { File { $ImportBody = Get-Content $JSONImport | ConvertFrom-Json | Select-Object -Property * -ExcludeProperty id, createdDateTime, lastModifiedDateTime, version, "@odata.context", apps@odata.context, deployedAppCount $ImportApps = $ImportBody.apps | Select-Object -Property * -ExcludeProperty id, version $ImportBody | Add-Member -MemberType NoteProperty -Name 'apps' -Value @($ImportApps) -Force } Object { $ImportBody = $PSBoundParameters.ImportObject | Select-Object -Property * -ExcludeProperty id, createdDateTime, lastModifiedDateTime, version, "@odata.context", apps@odata.context, deployedAppCount $ImportApps = $ImportBody.apps | Select-Object -Property * -ExcludeProperty id, version $ImportBody | Add-Member -MemberType NoteProperty -Name 'apps' -Value @($ImportApps) -Force } } $GraphImportParams = @{ Method = "POST" URI = "$GraphURI/deviceAppManagement/managedAppPolicies" BODY = ($ImportBody | ConvertTo-Json -Depth 10) Headers = $GraphHeader CONTENTTYPE = "application/Json" } Invoke-RestMethod @GraphImportParams } } function Export-AppProtectionPolicies { param( [Parameter(Mandatory = $True)] $PolicyID, [ValidateSet('Object', 'File')] [Parameter(Mandatory = $True)] $Type, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion" ) DynamicParam { #If the Import Param is used, Create the File Param switch ($Type) { File { $FileAttribute = New-Object System.Management.Automation.ParameterAttribute $FileAttribute.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom FileAttribute attribute $attributeCollection.Add($FileAttribute) #add our paramater specifying the attribute collection $ExportLocation = New-Object System.Management.Automation.RuntimeDefinedParameter('ExportLocation', [string], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('ExportLocation', $ExportLocation) return $paramDictionary } } } begin { IF ($PSBoundParameters.ExportLocation) { $ExportLocation = $PSBoundParameters.ExportLocation } IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } $GraphHeader = @{Authorization = "Bearer $($BGUAccessToken.AccessToken)" } } Process { $GraphObjectParams = @{ METHOD = "GET" URI = "$GraphURI/deviceAppManagement/managedAppPolicies/$($PolicyID)" HEADERS = $GraphHeader } $export_obj = Invoke-RestMethod @GraphObjectParams if ($export_obj) { switch ($Type) { Object { Switch ($export_obj.'@odata.type') { "#microsoft.graph.androidManagedAppProtection" { $GraphObjectParams = @{ METHOD = "GET" URI = "$GraphURI/deviceAppManagement/androidManagedAppProtections/$($PolicyID)?`$expand=apps" HEADERS = $GraphHeader } $appExport_obj = Invoke-RestMethod @GraphObjectParams $export_obj | Add-Member NoteProperty -Name 'apps' -Value @($appExport_obj.apps) } "#microsoft.graph.iosManagedAppProtection" { $GraphObjectParams = @{ METHOD = "GET" URI = "$GraphURI/deviceAppManagement/iosManagedAppProtections/$($PolicyID)?`$expand=apps" HEADERS = $GraphHeader } $appExport_obj = Invoke-RestMethod @GraphObjectParams $export_obj | Add-Member NoteProperty -Name 'apps' -Value @($appExport_obj.apps) } "#microsoft.graph.windowsInformationProtectionPolicy" { $GraphObjectParams = @{ METHOD = "GET" URI = "$GraphURI/deviceAppManagement/windowsInformationProtectionPolicies/$($PolicyID)?`$expand=protectedAppLockerFiles,exemptAppLockerFiles" HEADERS = $GraphHeader } $appExport_obj = Invoke-RestMethod @GraphObjectParams $export_obj | Add-Member NoteProperty -Name 'protectedAppLockerFiles' -Value @($appExport_obj.protectedAppLockerFiles) $export_obj | Add-Member NoteProperty -Name 'exemptAppLockerFiles' -Value @($appExport_obj.exemptAppLockerFiles) } "#microsoft.graph.mdmWindowsInformationProtectionPolicy" { $GraphObjectParams = @{ METHOD = "GET" URI = "$GraphURI/deviceAppManagement/mdmWindowsInformationProtectionPolicies/$($PolicyID)?`$expand=protectedAppLockerFiles,exemptAppLockerFiles" HEADERS = $GraphHeader } $appExport_obj = Invoke-RestMethod @GraphObjectParams $export_obj | Add-Member NoteProperty -Name 'protectedAppLockerFiles' -Value @($appExport_obj.protectedAppLockerFiles) $export_obj | Add-Member NoteProperty -Name 'exemptAppLockerFiles' -Value @($appExport_obj.exemptAppLockerFiles) } } $export_obj } File { #Get Apps Assigned to the Policy Switch ($export_obj.'@odata.type') { "#microsoft.graph.androidManagedAppProtection" { $GraphObjectParams = @{ METHOD = "GET" URI = "$GraphURI/deviceAppManagement/androidManagedAppProtections/$($PolicyID)?`$expand=apps" HEADERS = $GraphHeader } $appExport_obj = Invoke-RestMethod @GraphObjectParams ConvertTo-Json $app_Export_obj -Depth 10 | Out-File "$ExportLocation\$(($export_obj.displayName)).json" -Encoding ascii -Force } "#microsoft.graph.iosManagedAppProtection" { $GraphObjectParams = @{ METHOD = "GET" URI = "$GraphURI/deviceAppManagement/iosManagedAppProtections/$($PolicyID)?`$expand=apps" HEADERS = $GraphHeader } $appExport_obj = Invoke-RestMethod @GraphObjectParams ConvertTo-Json $app_Export_obj -Depth 10 | Out-File "$ExportLocation\$(($export_obj.displayName)).json" -Encoding ascii -Force } "#microsoft.graph.windowsInformationProtectionPolicy" { $GraphObjectParams = @{ METHOD = "GET" URI = "$GraphURI/deviceAppManagement/windowsInformationProtectionPolicies/$($PolicyID)?`$expand=protectedAppLockerFiles,exemptAppLockerFiles" HEADERS = $GraphHeader } $appExport_obj = Invoke-RestMethod @GraphObjectParams ConvertTo-Json $app_Export_obj -Depth 10 | Out-File "$ExportLocation\$(($export_obj.displayName)).json" -Encoding ascii -Force } "#microsoft.graph.mdmWindowsInformationProtectionPolicy" { $GraphObjectParams = @{ METHOD = "GET" URI = "$GraphURI/deviceAppManagement/mdmWindowsInformationProtectionPolicies/$($PolicyID)?`$expand=protectedAppLockerFiles,exemptAppLockerFiles" HEADERS = $GraphHeader } $appExport_obj = Invoke-RestMethod @GraphObjectParams ConvertTo-Json $app_Export_obj -Depth 10 | Out-File "$ExportLocation\$(($export_obj.displayName)).json" -Encoding ascii -Force } } } } } } } function Copy-AppProtectionPolicies { param( [string] [Parameter(Mandatory = $True)] $PolicyID, [Parameter(Mandatory = $True)] [ValidateSet('Copy', 'Test', 'PreProd', 'Dev', 'Prod', 'Pilot', 'Custom')] $Prefix, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion" ) DynamicParam { #If the Import Param is used, Create the File Param switch ($Prefix) { Custom { $CustomAttrib = New-Object System.Management.Automation.ParameterAttribute $CustomAttrib.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom CustomAttrib attribute $attributeCollection.Add($CustomAttrib) #add our paramater specifying the attribute collection $CustomPrefix = New-Object System.Management.Automation.RuntimeDefinedParameter('CustomPrefix', [string], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('CustomPrefix', $CustomPrefix) return $paramDictionary } } } begin { IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } switch ($Prefix) { Custom { $PolicyPrefix = $PSBoundParameters.CustomPrefix.ToUpper() } Default { $PolicyPrefix = $Prefix.ToUpper() } } } process { Write-Output "Object iD: $($PolicyID)" $BaseObject = Export-AppProtectionPolicies -Type Object $PolicyID | Select-Object -Property * -ExcludeProperty id, createdDateTime, lastModifiedDateTime, version, "@odata.context", apps@odata.context, deployedAppCount $BaseObject.displayName = "$PolicyPrefix-$($BaseObject.displayName)" Import-AppProtectionPolicies -Type Object -ImportObject $BaseObject } } #endregion AppProtection Policies #region Compliance Policies Function Get-CompliancePolicies { <# .SYNOPSIS This function is used to get Compliance Policies from the GraphAPI Associated with your connected tenant. .DESCRIPTION This function is used to get Compliance Policies from the GraphAPI Associated with your connected tenant. It is possible to filter these by using -Type FilterQuery -FilterID <policyID>, you can also user Where-Object to filter these. .EXAMPLE PS C:\> Get-CompliancePolicies This will return all of the policies within your connected tenant .EXAMPLE PS C:\> Get-CompliancePolicies -Type FilterQuery -FilterID <PolicyID> This will return the single policy for the ID you specify .INPUTS -Type : Used when you want to specify if you want to Filter the ID. -FilterID : The ID of the Policy .OUTPUTS Sample: @odata.type : #microsoft.graph.windows10CompliancePolicy roleScopeTagIds : {0} id : 148f61df-xxxx-xxxx-xxxx-e0202a883a7c createdDateTime : 2020-10-30T05:52:25.7143691Z description : lastModifiedDateTime : 2020-10-30T05:52:25.7143691Z displayName : Compliance_Device_Security version : 1 passwordRequired : False passwordBlockSimple : False passwordRequiredToUnlockFromIdle : False passwordMinutesOfInactivityBeforeLock : passwordExpirationDays : passwordMinimumLength : passwordMinimumCharacterSetCount : passwordRequiredType : deviceDefault passwordPreviousPasswordBlockCount : requireHealthyDeviceReport : False osMinimumVersion : osMaximumVersion : mobileOsMinimumVersion : mobileOsMaximumVersion : earlyLaunchAntiMalwareDriverEnabled : False bitLockerEnabled : False secureBootEnabled : False codeIntegrityEnabled : False storageRequireEncryption : False activeFirewallRequired : True defenderEnabled : False defenderVersion : signatureOutOfDate : False rtpEnabled : False antivirusRequired : True antiSpywareRequired : False deviceThreatProtectionEnabled : False deviceThreatProtectionRequiredSecurityLevel : unavailable configurationManagerComplianceRequired : False tpmRequired : False deviceCompliancePolicyScript : validOperatingSystemBuildRanges : {} scheduledActionsForRule@odata.context : https://graph.microsoft.com/beta/$metadata#deviceManagement/deviceCompliancePolicies('148f61df-e7a3-40f2-b728-e0202a883a7c')/microsoft.graph.windows10CompliancePolicy/schedul edActionsForRule(scheduledActionConfigurations()) scheduledActionsForRule : {@{id=148f61df-xxxx-xxxx-xxxx-e0202a883a7c; ruleName=; scheduledActionConfigurations@odata.context=https://graph.microsoft.com/beta/$metadata#deviceManagement/deviceComplianc ePolicies('148f61df-xxxx-xxxx-xxxx-e0202a883a7c')/microsoft.graph.windows10CompliancePolicy/scheduledActionsForRule('148f61df-xxxx-xxxx-xxxx-e0202a883a7c')/scheduledActionCon figurations; scheduledActionConfigurations=System.Object[]}} .NOTES #> [CmdletBinding()] param ( [ValidateSet('All', 'FilterQuery')] $Type, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion" ) DynamicParam { #If the Import Param is used, Create the File Param switch ($Type) { FilterQuery { $FAttrib = New-Object System.Management.Automation.ParameterAttribute $FAttrib.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom FileAttribute attribute $attributeCollection.Add($FAttrib) #add our paramater specifying the attribute collection $FilterID = New-Object System.Management.Automation.RuntimeDefinedParameter('FilterID', [string], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('FilterID', $FilterID) return $paramDictionary } } } begin { IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } $GraphHeader = @{Authorization = "Bearer $($BGUAccessToken.AccessToken)" } } #Process The Function Process { try { $GraphParams = @{ Method = "GET" URI = "$GraphURI/deviceManagement/deviceCompliancePolicies?`$expand=scheduledActionsForRule(`$expand=scheduledActionConfigurations)" Headers = $GraphHeader } $GraphRequest = Invoke-RestMethod @GraphParams -ErrorAction Stop $All_GraphRequest = @() $All_GraphRequest += $GraphRequest while ($GraphRequest.'@odata.nextLink') { $GraphRequest_NextLink = @{ Method = "GET" URI = $GraphRequest.'@odata.nextLink' Headers = $GraphHeader ContentType = "application/JSON" } $GraphRequest = Invoke-RestMethod @GraphRequest_NextLink -ErrorAction Stop $All_GraphRequest += $GraphRequest } } catch { $Error[0] Throw "The Microsoft Graph Query Failed," } Switch ($Type) { Default { $All_GraphRequest | Select-Object -ExpandProperty Value } FilterQuery { $All_GraphRequest | Select-Object -ExpandProperty Value | Where-Object id -Match $($PSBoundParameters.FilterID) } } } } Function Import-CompliancePolicies { [CmdletBinding()] param ( [ValidateSet('Object', 'File')] $Type, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion" ) DynamicParam { switch ($Type) { File { #If the Import Param is used, Create the File Param $FileAttribute = New-Object System.Management.Automation.ParameterAttribute $FileAttribute.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom FileAttribute attribute $attributeCollection.Add($FileAttribute) #add our paramater specifying the attribute collection $File = New-Object System.Management.Automation.RuntimeDefinedParameter('File', [string], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('File', $File) return $paramDictionary } Object { $ObjectAttrib = New-Object System.Management.Automation.ParameterAttribute $ObjectAttrib.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom ObjectAttrib attribute $attributeCollection.Add($ObjectAttrib) #add our paramater specifying the attribute collection $ImportObject = New-Object System.Management.Automation.RuntimeDefinedParameter('ImportObject', [Object], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('ImportObject', $ImportObject) return $paramDictionary } } } begin { IF ($PSBoundParameters.File) { IF (-not (Test-Path -Path $PSBoundParameters.File)) { Throw "Unable to locate $PSBoundParameters.File" } else { $JSONImport = $PSBoundParameters.File } } IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } $GraphHeader = @{Authorization = "Bearer $($BGUAccessToken.AccessToken)" } } #Process The Function Process { switch ($Type) { File { $ImportBody = Get-Content $JSONImport | ConvertFrom-Json | Select-Object -Property * -ExcludeProperty Version, lastModifiedDateTime, CreatedDateTime, id, scheduledActionsForRule@odata.context IF (-Not ($ImportBody.scheduledActionsForRule)) { $SAFRuleOBJ = @( @{ "ruleName" = "PasswordRequired" "scheduledActionConfigurations" = @( @{ "actionType" = "block" "gracePeriodHours" = 0 "notificationTemplateId" = "" "notificationMessageCCList" = @() } ) } ) $ImportBody | Add-Member -MemberType NoteProperty -Name "scheduledActionsForRule" -Value $SAFRuleOBJ } else { $CurrentSettings = $ImportBody.scheduledActionsForRule | Select-Object * -ExcludeProperty id, scheduledActionConfigurations@odata.context $CurrentSettings_SAC = $CurrentSettings.scheduledActionConfigurations | Select-Object * -ExcludeProperty id IF ($CurrentSettings_SAC.notificationTemplateId -match "00000000-0000-0000-0000-000000000000") { $CurrentSettings_SAC.notificationTemplateId = "" } $CurrentSettings.scheduledActionConfigurations = @($CurrentSettings_SAC) $ImportBody.scheduledActionsForRule = @($CurrentSettings) #$ImportBody.scheduledActionsForRule.scheduledActionConfigurations = $CurrentSettings_SAC } } Object { $ImportBody = $PSBoundParameters.ImportObject | Select-Object -Property * -ExcludeProperty Version, lastModifiedDateTime, CreatedDateTime, id, supportsScopeTags, lastModifiedDateTime IF (-Not ($ImportBody.scheduledActionsForRule)) { $SAFRuleOBJ = @( @{ "ruleName" = "PasswordRequired" "scheduledActionConfigurations" = @( @{ "actionType" = "block" "gracePeriodHours" = 0 "notificationTemplateId" = "" "notificationMessageCCList" = @() } ) } ) $ImportBody | Add-Member -MemberType NoteProperty -Name "scheduledActionsForRule" -Value $SAFRuleOBJ } else { $CurrentSettings = $ImportBody.scheduledActionsForRule | Select-Object * -ExcludeProperty id, scheduledActionConfigurations@odata.context $CurrentSettings_SAC = $CurrentSettings.scheduledActionConfigurations | Select-Object * -ExcludeProperty id IF ($CurrentSettings_SAC.notificationTemplateId -match "00000000-0000-0000-0000-000000000000") { $CurrentSettings_SAC.notificationTemplateId = "" } $CurrentSettings.scheduledActionConfigurations = @($CurrentSettings_SAC) $ImportBody.scheduledActionsForRule = @($CurrentSettings) } } } $GraphImportParams = @{ Method = "POST" URI = "$GraphURI/deviceManagement/deviceCompliancePolicies" BODY = ($ImportBody | ConvertTo-Json -Depth 10) Headers = $GraphHeader CONTENTTYPE = "application/Json" } Invoke-RestMethod @GraphImportParams } } function Export-CompliancePolicies { param( [Parameter(Mandatory = $True)] $PolicyID, [ValidateSet('Object', 'File')] [Parameter(Mandatory = $True)] $Type, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion" ) DynamicParam { #If the Import Param is used, Create the File Param switch ($Type) { File { $FileAttribute = New-Object System.Management.Automation.ParameterAttribute $FileAttribute.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom FileAttribute attribute $attributeCollection.Add($FileAttribute) #add our paramater specifying the attribute collection $ExportLocation = New-Object System.Management.Automation.RuntimeDefinedParameter('ExportLocation', [string], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('ExportLocation', $ExportLocation) return $paramDictionary } } } begin { IF ($PSBoundParameters.ExportLocation) { $ExportLocation = $PSBoundParameters.ExportLocation } IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } $GraphHeader = @{Authorization = "Bearer $($BGUAccessToken.AccessToken)" } } Process { $GraphObjectParams = @{ METHOD = "GET" URI = "$GraphURI/deviceManagement/deviceCompliancePolicies/$($PolicyID)?`$expand=scheduledActionsForRule(`$expand=scheduledActionConfigurations)" HEADERS = $GraphHeader } $export_obj = Invoke-RestMethod @GraphObjectParams if ($export_obj) { switch ($Type) { Object { $export_obj } File { # Export The Base Admin Template ConvertTo-Json $export_obj -Depth 10 | Out-File "$ExportLocation\$(($export_obj.displayName)).json" -Encoding ascii -Force } } } } } function Copy-CompliancePolicies { param( [string] [Parameter(Mandatory = $True)] $PolicyID, [Parameter(Mandatory = $True)] [ValidateSet('Copy', 'Test', 'PreProd', 'Dev', 'Prod', 'Pilot', 'Custom')] $Prefix, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion" ) DynamicParam { #If the Import Param is used, Create the File Param switch ($Prefix) { Custom { $CustomAttrib = New-Object System.Management.Automation.ParameterAttribute $CustomAttrib.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom CustomAttrib attribute $attributeCollection.Add($CustomAttrib) #add our paramater specifying the attribute collection $CustomPrefix = New-Object System.Management.Automation.RuntimeDefinedParameter('CustomPrefix', [string], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('CustomPrefix', $CustomPrefix) return $paramDictionary } } } begin { IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } switch ($Prefix) { Custom { $PolicyPrefix = $PSBoundParameters.CustomPrefix.ToUpper() } Default { $PolicyPrefix = $Prefix.ToUpper() } } } process { Write-Output "Object iD: $($PolicyID)" $BaseObject = Export-CompliancePolicies -Type Object $PolicyID $BaseObject.displayName = "$PolicyPrefix-$($BaseObject.displayName)" Import-CompliancePolicies -Type Object -ImportObject $BaseObject } } #endregion Compliance Policies #region Conditional Access Policies Function Get-ConditionalAccessPolicies { <# .SYNOPSIS This function is used to get Conditional Access policies from the GraphAPI Associated with your connected tenant. .DESCRIPTION This function is used to get Conditional Access policies from the GraphAPI Associated with your connected tenant. It is possible to filter these by using -Type FilterQuery -FilterID <policyID>, you can also user Where-Object to filter these. .EXAMPLE PS C:\> Get-ConditionalAccessPolicies This will return all of the policies within your connected tenant .EXAMPLE PS C:\> Get-ConditionalAccessPolicies -Type FilterQuery -FilterID <PolicyID> This will return the single policy for the ID you specify .INPUTS -Type : Used when you want to specify if you want to Filter the ID. -FilterID : The ID of the Policy .OUTPUTS .NOTES This requires you to call the Get-BGUAccess Token with a Delegate ID, Use Get-Help -Name Get-BGUAccessToken -Full for more details and visit https://euc365.com/backup-and-import-conditional-access-policies/ for additional Information #> [CmdletBinding()] param ( [ValidateSet('All', 'FilterQuery')] $Type, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion" ) DynamicParam { #If the Import Param is used, Create the File Param switch ($Type) { FilterQuery { $FAttrib = New-Object System.Management.Automation.ParameterAttribute $FAttrib.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom FileAttribute attribute $attributeCollection.Add($FAttrib) #add our paramater specifying the attribute collection $FilName = New-Object System.Management.Automation.RuntimeDefinedParameter('FilterID', [string], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('FilterID', $FilName) return $paramDictionary } } } begin { IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } $GraphHeader = @{Authorization = "Bearer $($BGUAccessToken.AccessToken)" } } #Process The Function Process { try { $GraphParams = @{ Method = "GET" URI = "$GraphURI/identity/conditionalAccess/policies" Headers = $GraphHeader } $GraphRequest = Invoke-RestMethod @GraphParams -ErrorAction Stop $All_GraphRequest = @() $All_GraphRequest += $GraphRequest while ($GraphRequest.'@odata.nextLink') { $GraphRequest_NextLink = @{ Method = "GET" URI = $GraphRequest.'@odata.nextLink' Headers = $GraphHeader ContentType = "application/JSON" } $GraphRequest = Invoke-RestMethod @GraphRequest_NextLink -ErrorAction Stop $All_GraphRequest += $GraphRequest } } catch { $Error[0] Throw "The Microsoft Graph Query Failed," } Switch ($Type) { Default { $All_GraphRequest | Select-Object -ExpandProperty Value } FilterQuery { $All_GraphRequest | Select-Object -ExpandProperty Value | Where-Object id -Match $($PSBoundParameters.FilterID) } } } } Function Import-ConditionalAccessPolicies { [CmdletBinding()] param ( [ValidateSet('Object', 'File')] $Type, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion" ) DynamicParam { switch ($Type) { File { #If the Import Param is used, Create the File Param $FileAttribute = New-Object System.Management.Automation.ParameterAttribute $FileAttribute.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom FileAttribute attribute $attributeCollection.Add($FileAttribute) #add our paramater specifying the attribute collection $File = New-Object System.Management.Automation.RuntimeDefinedParameter('File', [string], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('File', $File) return $paramDictionary } Object { $ObjectAttrib = New-Object System.Management.Automation.ParameterAttribute $ObjectAttrib.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom ObjectAttrib attribute $attributeCollection.Add($ObjectAttrib) #add our paramater specifying the attribute collection $ImportObject = New-Object System.Management.Automation.RuntimeDefinedParameter('ImportObject', [Object], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('ImportObject', $ImportObject) return $paramDictionary } } } begin { IF ($PSBoundParameters.File) { IF (-not (Test-Path -Path $PSBoundParameters.File)) { Throw "Unable to locate $PSBoundParameters.File" } else { $JSONImport = $PSBoundParameters.File } } IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } $GraphHeader = @{Authorization = "Bearer $($BGUAccessToken.AccessToken)" } } Process { switch ($Type) { File { $ImportBody = Get-Content $JSONImport | ConvertFrom-Json | Select-Object -Property * -ExcludeProperty Version, ModifiedDateTime, CreatedDateTime, id, supportsScopeTags } Object { $ImportBody = $PSBoundParameters.ImportObject | Select-Object -Property * -ExcludeProperty Version, ModifiedDateTime, CreatedDateTime, id, supportsScopeTags } } $GraphImportParams = @{ Method = "POST" URI = "$GraphURI/identity/conditionalAccess/policies" BODY = ($ImportBody | ConvertTo-Json -Depth 10) Headers = $GraphHeader CONTENTTYPE = "application/Json" } Invoke-RestMethod @GraphImportParams } } function Export-ConditionalAccessPolicies { param( [Parameter(Mandatory = $True)] $PolicyID, [ValidateSet('Object', 'File')] [Parameter(Mandatory = $True)] $Type, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion" ) DynamicParam { #If the Import Param is used, Create the File Param switch ($Type) { File { $FileAttribute = New-Object System.Management.Automation.ParameterAttribute $FileAttribute.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom FileAttribute attribute $attributeCollection.Add($FileAttribute) #add our paramater specifying the attribute collection $ExportLocation = New-Object System.Management.Automation.RuntimeDefinedParameter('ExportLocation', [string], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('ExportLocation', $ExportLocation) return $paramDictionary } } } begin { IF ($PSBoundParameters.ExportLocation) { $ExportLocation = $PSBoundParameters.ExportLocation } IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } $GraphHeader = @{Authorization = "Bearer $($BGUAccessToken.AccessToken)" } } Process { $GraphObjectParams = @{ METHOD = "GET" URI = "$GraphURI/identity/conditionalAccess/policies/$($PolicyID)" HEADERS = $GraphHeader } $export_obj = Invoke-RestMethod @GraphObjectParams if ($export_obj) { switch ($Type) { Object { $export_obj } File { # Export The Base Admin Template ConvertTo-Json $export_obj -Depth 10 | Out-File "$ExportLocation\$(($export_obj.displayName)).json" -Encoding ascii -Force } } } } } function Copy-ConditionalAccessPolicies { param( [string] [Parameter(Mandatory = $True)] $PolicyID, [Parameter(Mandatory = $True)] [ValidateSet('Copy', 'Test', 'PreProd', 'Dev', 'Prod', 'Pilot', 'Custom')] $Prefix, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion" ) DynamicParam { #If the Import Param is used, Create the File Param switch ($Prefix) { Custom { $CustomAttrib = New-Object System.Management.Automation.ParameterAttribute $CustomAttrib.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom CustomAttrib attribute $attributeCollection.Add($CustomAttrib) #add our paramater specifying the attribute collection $CustomPrefix = New-Object System.Management.Automation.RuntimeDefinedParameter('CustomPrefix', [string], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('CustomPrefix', $CustomPrefix) return $paramDictionary } } } begin { IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } switch ($Prefix) { Custom { $PolicyPrefix = $PSBoundParameters.CustomPrefix.ToUpper() } Default { $PolicyPrefix = $Prefix.ToUpper() } } } process { Write-Output "Object iD: $($PolicyID)" $BaseObject = Export-ConditionalAccessPolicies -Type Object -PolicyID $PolicyID $BaseObject.displayName = "$PolicyPrefix-$($BaseObject.displayName)" Import-ConditionalAccessPolicies -Type Object -ImportObject $BaseObject } } #endregion Conditional Access Policies #region Configuration Profiles Function Get-ConfigurationProfiles { <# .SYNOPSIS This function is used to get Configuration Profiles from the GraphAPI Associated with your connected tenant. .DESCRIPTION This function is used to get Configuration Profiles from the GraphAPI Associated with your connected tenant. It is possible to filter these by using -Type FilterQuery -FilterID <policyID>, you can also user Where-Object to filter these. .EXAMPLE PS C:\> Get-ConfigurationProfiles This will return all of the policies within your connected tenant .EXAMPLE PS C:\> Get-ConfigurationProfiles -Type FilterQuery -FilterID <PolicyID> This will return the single policy for the ID you specify .INPUTS -Type : Used when you want to specify if you want to Filter the ID. -FilterID : The ID of the Policy .OUTPUTS .NOTES This covers all policies, excluding the settings catalogue, Administrative Templates and Endpoint Security Profiles #> [CmdletBinding()] param ( [ValidateSet('All', 'FilterQuery')] $Type, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion" ) DynamicParam { #If the Import Param is used, Create the File Param switch ($Type) { FilterQuery { $FAttrib = New-Object System.Management.Automation.ParameterAttribute $FAttrib.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom FileAttribute attribute $attributeCollection.Add($FAttrib) #add our paramater specifying the attribute collection $FilterID = New-Object System.Management.Automation.RuntimeDefinedParameter('FilterID', [string], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('FilterID', $FilterID) return $paramDictionary } } } begin { IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } $GraphHeader = @{Authorization = "Bearer $($BGUAccessToken.AccessToken)" } } #Process The Function Process { try { $GraphParams = @{ Method = "GET" URI = "$GraphURI/deviceManagement/deviceConfigurations" Headers = $GraphHeader } $GraphRequest = Invoke-RestMethod @GraphParams -ErrorAction Stop $All_GraphRequest = @() $All_GraphRequest += $GraphRequest while ($GraphRequest.'@odata.nextLink') { $GraphRequest_NextLink = @{ Method = "GET" URI = $GraphRequest.'@odata.nextLink' Headers = $GraphHeader ContentType = "application/JSON" } $GraphRequest = Invoke-RestMethod @GraphRequest_NextLink -ErrorAction Stop $All_GraphRequest += $GraphRequest } } catch { $Error[0] Throw "The Microsoft Graph Query Failed," } Switch ($Type) { Default { $All_GraphRequest | Select-Object -ExpandProperty Value } FilterQuery { $All_GraphRequest | Select-Object -ExpandProperty Value | Where-Object id -Match $($PSBoundParameters.FilterID) } } } } Function Import-ConfigurationProfiles { [CmdletBinding()] param ( [ValidateSet('Object', 'File')] $Type, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion" ) DynamicParam { switch ($Type) { File { #If the Import Param is used, Create the File Param $FileAttribute = New-Object System.Management.Automation.ParameterAttribute $FileAttribute.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom FileAttribute attribute $attributeCollection.Add($FileAttribute) #add our paramater specifying the attribute collection $File = New-Object System.Management.Automation.RuntimeDefinedParameter('File', [string], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('File', $File) return $paramDictionary } Object { $ObjectAttrib = New-Object System.Management.Automation.ParameterAttribute $ObjectAttrib.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom ObjectAttrib attribute $attributeCollection.Add($ObjectAttrib) #add our paramater specifying the attribute collection $ImportObject = New-Object System.Management.Automation.RuntimeDefinedParameter('ImportObject', [Object] , $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('ImportObject', $ImportObject) return $paramDictionary } } } begin { #If the File Param is used, Test the Path to make sure its accessible, If not throw an error. If it does exist set the JSONImport Param to the AttributeValue IF ($PSBoundParameters.File) { IF (-not (Test-Path -Path $PSBoundParameters.File)) { Throw "Unable to locate $PSBoundParameters.File" } else { $JSONImport = $PSBoundParameters.File } } IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } $GraphHeader = @{Authorization = "Bearer $($BGUAccessToken.AccessToken)" } } #Process The Function Process { switch ($Type) { File { $ImportBody = Get-Content $JSONImport | ConvertFrom-Json | Select-Object -Property * -ExcludeProperty Version, LastModifiedDateTime, CreatedDateTime, id | ConvertTo-Json -Depth 10 } Object { $ImportBody = $PSBoundParameters.ImportObject | Select-Object -Property * -ExcludeProperty Version, LastModifiedDateTime, CreatedDateTime, id, supportsScopeTags, lastModifiedDateTime | ConvertTo-Json -Depth 10 } } $GraphImportParams = @{ Method = "POST" URI = "$GraphURI/deviceManagement/deviceConfigurations" BODY = $ImportBody Headers = $GraphHeader CONTENTTYPE = "application/Json" } Invoke-RestMethod @GraphImportParams } } function Export-ConfigurationProfiles { param( [Parameter(Mandatory = $True)] $PolicyID, [ValidateSet('Object', 'File')] [Parameter(Mandatory = $True)] $Type, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion" ) DynamicParam { #If the Import Param is used, Create the File Param switch ($Type) { File { $FileAttribute = New-Object System.Management.Automation.ParameterAttribute $FileAttribute.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom FileAttribute attribute $attributeCollection.Add($FileAttribute) #add our paramater specifying the attribute collection $ExportLocation = New-Object System.Management.Automation.RuntimeDefinedParameter('ExportLocation', [string], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('ExportLocation', $ExportLocation) return $paramDictionary } } } begin { IF ($PSBoundParameters.ExportLocation) { $ExportLocation = $PSBoundParameters.ExportLocation } IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } $GraphHeader = @{Authorization = "Bearer $($BGUAccessToken.AccessToken)" } } Process { $GraphObjectParams = @{ METHOD = "GET" URI = "$GraphURI/deviceManagement/deviceConfigurations/$($PolicyID)" HEADERS = $GraphHeader } $export_obj = Invoke-RestMethod @GraphObjectParams if ($export_obj) { switch ($Type) { Object { $export_obj } File { # Export The Base Admin Template ConvertTo-Json $export_obj -Depth 10 | Out-File "$ExportLocation\$(($export_obj.displayName)).json" -Encoding ascii -Force } } } } } function Copy-ConfigurationProfiles { param( [string] [Parameter(Mandatory = $True)] $PolicyID, [Parameter(Mandatory = $True)] [ValidateSet('Copy', 'Test', 'PreProd', 'Dev', 'Prod', 'Pilot', 'Custom')] $Prefix, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion" ) DynamicParam { #If the Import Param is used, Create the File Param switch ($Prefix) { Custom { $CustomAttrib = New-Object System.Management.Automation.ParameterAttribute $CustomAttrib.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom CustomAttrib attribute $attributeCollection.Add($CustomAttrib) #add our paramater specifying the attribute collection $CustomPrefix = New-Object System.Management.Automation.RuntimeDefinedParameter('CustomPrefix', [string], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('CustomPrefix', $CustomPrefix) return $paramDictionary } } } begin { IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } switch ($Prefix) { Custom { $PolicyPrefix = $PSBoundParameters.CustomPrefix.ToUpper() } Default { $PolicyPrefix = $Prefix.ToUpper() } } } process { Write-Output "Object iD: $($PolicyID)" $BaseObject = Export-ConfigurationProfiles -Type Object $PolicyID $BaseObject.displayName = "$PolicyPrefix-$($BaseObject.displayName)" Import-ConfigurationProfiles -Type Object -ImportObject $BaseObject } } #endregion Configuration Profiles #region Endpoint Security Profiles Function Get-EndpointSecurityProfiles { <# .SYNOPSIS This function is used to get Endpoint Security Profile policies from the GraphAPI Associated with your connected tenant. .DESCRIPTION This function is used to get Endpoint Security Profile policies from the GraphAPI Associated with your connected tenant. It is possible to filter these by using -Type FilterQuery -FilterID <policyID>, you can also user Where-Object to filter these. .EXAMPLE PS C:\> Get-EndpointSecurityProfiles This will return all of the policies within your connected tenant .EXAMPLE PS C:\> Get-EndpointSecurityProfiles -Type FilterQuery -FilterID <PolicyID> This will return the single policy for the ID you specify .INPUTS -Type : Used when you want to specify if you want to Filter the ID. -FilterID : The ID of the Policy .OUTPUTS Sample: id : f460338c-xxxx-xxxx-xxxx-e41053d5227f displayName : Firewall_Policy description : isAssigned : False lastModifiedDateTime : 2021-04-16T14:23:07.5112048Z templateId : c53e5a9f-2eec-4175-98a1-2b3d38084b91 roleScopeTagIds : {0} .NOTES #> [CmdletBinding()] param ( [ValidateSet('All', 'FilterQuery')] $Type, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion" ) DynamicParam { #If the Import Param is used, Create the File Param switch ($Type) { FilterQuery { $FAttrib = New-Object System.Management.Automation.ParameterAttribute $FAttrib.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom FileAttribute attribute $attributeCollection.Add($FAttrib) #add our paramater specifying the attribute collection $FilterID = New-Object System.Management.Automation.RuntimeDefinedParameter('FilterID', [string], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('FilterID', $FilterID) return $paramDictionary } } } begin { IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } $GraphHeader = @{Authorization = "Bearer $($BGUAccessToken.AccessToken)" } } #Process The Function Process { try { $GraphParams = @{ Method = "GET" URI = "$GraphURI/deviceManagement/intents" Headers = $GraphHeader } $GraphRequest = Invoke-RestMethod @GraphParams -ErrorAction Stop $All_GraphRequest = @() $All_GraphRequest += $GraphRequest while ($GraphRequest.'@odata.nextLink') { $GraphRequest_NextLink = @{ Method = "GET" URI = $GraphRequest.'@odata.nextLink' Headers = $GraphHeader ContentType = "application/JSON" } $GraphRequest = Invoke-RestMethod @GraphRequest_NextLink -ErrorAction Stop $All_GraphRequest += $GraphRequest } } catch { $Error[0] Throw "The Microsoft Graph Query Failed," } Switch ($Type) { Default { $All_GraphRequest | Select-Object -ExpandProperty Value } FilterQuery { $All_GraphRequest | Select-Object -ExpandProperty Value | Where-Object id -Match $($PSBoundParameters.FilterID) } } } } Function Import-EndpointSecurityProfiles { [CmdletBinding()] param ( [ValidateSet('Object', 'File')] $Type, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion" ) DynamicParam { switch ($Type) { File { #If the Import Param is used, Create the File Param $FileAttribute = New-Object System.Management.Automation.ParameterAttribute $FileAttribute.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom FileAttribute attribute $attributeCollection.Add($FileAttribute) #add our paramater specifying the attribute collection $File = New-Object System.Management.Automation.RuntimeDefinedParameter('File', [string], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('File', $File) return $paramDictionary } Object { $ObjectAttrib = New-Object System.Management.Automation.ParameterAttribute $ObjectAttrib.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom ObjectAttrib attribute $attributeCollection.Add($ObjectAttrib) #add our paramater specifying the attribute collection $ImportObject = New-Object System.Management.Automation.RuntimeDefinedParameter('ImportObject', [array] , $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('ImportObject', $ImportObject) return $paramDictionary } } } begin { #If the File Param is used, Test the Path to make sure its accessible, If not throw an error. If it does exist set the JSONImport Param to the AttributeValue IF ($PSBoundParameters.File) { IF (-not (Test-Path -Path $PSBoundParameters.File)) { Throw "Unable to locate $PSBoundParameters.File" } else { $JSONImport = $PSBoundParameters.File } } IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } $GraphHeader = @{Authorization = "Bearer $($BGUAccessToken.AccessToken)" } } #Process The Function Process { switch ($Type) { File { $JSONContent = Get-Content $JSONImport | ConvertFrom-Json $TemplateID = $JSONContent.templateID $ImportBody = $JSONContent | Select-Object -Property * -ExcludeProperty templateID } Object { $TemplateID = $PSBoundParameters.ImportObject.templateID $ImportBody = @{ "displayName" = $PSBoundParameters.ImportObject.displayName "description" = $PSBoundParameters.ImportObject.description "settingDelta" = $PSBoundParameters.ImportObject.settingDelta "roleScopeTagIds" = @($PSBoundParameters.ImportObject.roleScopeTagIds) } } } $GraphImportParams = @{ Method = "POST" URI = "$GraphURI/deviceManagement/templates/$($TemplateID)/createinstance" BODY = ($ImportBody | ConvertTo-Json -Depth 10 ) Headers = $GraphHeader CONTENTTYPE = "application/Json" } Invoke-RestMethod @GraphImportParams } } function Export-EndpointSecurityProfiles { param( [Parameter(Mandatory = $True)] $PolicyID, [ValidateSet('Object', 'File')] [Parameter(Mandatory = $True)] $Type, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion" ) DynamicParam { #If the Import Param is used, Create the File Param switch ($Type) { File { $FileAttribute = New-Object System.Management.Automation.ParameterAttribute $FileAttribute.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom FileAttribute attribute $attributeCollection.Add($FileAttribute) #add our paramater specifying the attribute collection $ExportLocation = New-Object System.Management.Automation.RuntimeDefinedParameter('ExportLocation', [string], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('ExportLocation', $ExportLocation) return $paramDictionary } } } begin { IF ($PSBoundParameters.ExportLocation) { $ExportLocation = $PSBoundParameters.ExportLocation } IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } $GraphHeader = @{Authorization = "Bearer $($BGUAccessToken.AccessToken)" } } Process { $GraphDeviceIntentParams = @{ METHOD = "GET" URI = "$GraphURI/deviceManagement/Intents/$($PolicyID)" HEADERS = $GraphHeader } $IntentPolicy = Invoke-RestMethod @GraphDeviceIntentParams if ($IntentPolicy) { $GraphTemplateCategoriesParams = @{ METHOD = "GET" URI = "$GraphURI/deviceManagement/templates/$($IntentPolicy.templateId)/categories" HEADERS = $GraphHeader } $IntentPolicy_Template_Categories = Invoke-RestMethod @GraphTemplateCategoriesParams $All_IntentPolicy_Template_Categories = @() $All_IntentPolicy_Template_Categories += $IntentPolicy_Template_Categories while ($IntentPolicy_Template_Categories.'@odata.nextLink') { $GraphRequest_NextLink = @{ Method = "GET" URI = $IntentPolicy_Template_Categories.'@odata.nextLink' Headers = $GraphHeader ContentType = "application/JSON" } $IntentPolicy_Template_Categories = Invoke-RestMethod @GraphRequest_NextLink -ErrorAction Stop $All_IntentPolicy_Template_Categories += $IntentPolicy_Template_Categories } $IntentPolicy_Settings = @() FOREACH ($Category in $All_IntentPolicy_Template_Categories.value) { $GraphIntentSettingParams = @{ METHOD = "GET" URI = "$GraphURI/deviceManagement/intents/$($IntentPolicy.Id)/categories/$($Category.id)/settings" HEADERS = $GraphHeader } $IntentPolicy_Settings += Invoke-RestMethod @GraphIntentSettingParams $All_IntentPolicy_Settings = @() $All_IntentPolicy_Settings += $IntentPolicy_Settings while ($IntentPolicy_Settings.'@odata.nextLink') { $GraphRequest_NextLink = @{ Method = "GET" URI = $IntentPolicy_Settings.'@odata.nextLink' Headers = $GraphHeader ContentType = "application/JSON" } $IntentPolicy_Settings = Invoke-RestMethod @GraphRequest_NextLink -ErrorAction Stop $All_IntentPolicy_Settings += $IntentPolicy_Settings } } $export_obj = @{ "displayName" = $IntentPolicy.displayName "templateID" = $IntentPolicy.templateId "description" = $IntentPolicy.description "settingsDelta" = $All_IntentPolicy_Settings.value "roleScopeTagIds" = $IntentPolicy.roleScopeTagIds } switch ($Type) { Object { $export_obj } File { # Export The Base Admin Template ConvertTo-Json $export_obj -Depth 10 | Out-File "$ExportLocation\$(($export_obj.displayName)).json" -Encoding ascii -Force } } } } } function Copy-EndpointSecurityProfiles { param( [string] [Parameter(Mandatory = $True)] $PolicyID, [Parameter(Mandatory = $True)] [ValidateSet('Copy', 'Test', 'PreProd', 'Dev', 'Prod', 'Pilot', 'Custom')] $Prefix, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion" ) DynamicParam { #If the Import Param is used, Create the File Param switch ($Prefix) { Custom { $CustomAttrib = New-Object System.Management.Automation.ParameterAttribute $CustomAttrib.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom CustomAttrib attribute $attributeCollection.Add($CustomAttrib) #add our paramater specifying the attribute collection $CustomPrefix = New-Object System.Management.Automation.RuntimeDefinedParameter('CustomPrefix', [string], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('CustomPrefix', $CustomPrefix) return $paramDictionary } } } begin { IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } switch ($Prefix) { Custom { $PolicyPrefix = $PSBoundParameters.CustomPrefix.ToUpper() } Default { $PolicyPrefix = $Prefix.ToUpper() } } } process { Write-Output "Object iD: $($PolicyID)" $BaseObject = Export-EndpointSecurityProfiles -Type Object $PolicyID $BaseObject.displayName = "$PolicyPrefix-$($BaseObject.displayName)" Import-EndpointSecurityProfiles -Type Object -ImportObject $BaseObject } } #endregion Endpoint Security Profiles #region OEMConfig Function Get-OEMConfigProfile { <# .SYNOPSIS This function is used to get OEMConfig Profiles from the GraphAPI Associated with your connected tenant. .DESCRIPTION This function is used to get OEMConfig Profiles from the GraphAPI Associated with your connected tenant. It is possible to filter these by using -Type FilterQuery -FilterID <policyID>, you can also user Where-Object to filter these. .EXAMPLE PS C:\> Get-OEMConfigProfile This will return all of the policies within your connected tenant .EXAMPLE PS C:\> Get-OEMConfigProfile -Type FilterQuery -FilterID <PolicyID> This will return the single policy for the ID you specify .INPUTS -Type : Used when you want to specify if you want to Filter the ID. -FilterID : The ID of the Policy .OUTPUTS .NOTES This covers all policies, excluding the settings catalogue, Administrative Templates and Endpoint Security Profiles #> [CmdletBinding()] param ( [ValidateSet('All', 'FilterQuery')] $Type, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion" ) DynamicParam { #If the Import Param is used, Create the File Param switch ($Type) { FilterQuery { $FAttrib = New-Object System.Management.Automation.ParameterAttribute $FAttrib.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom FileAttribute attribute $attributeCollection.Add($FAttrib) #add our paramater specifying the attribute collection $FilterID = New-Object System.Management.Automation.RuntimeDefinedParameter('FilterID', [string], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('FilterID', $FilterID) return $paramDictionary } } } begin { IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } $GraphHeader = @{Authorization = "Bearer $($BGUAccessToken.AccessToken)" } } #Process The Function Process { try { $GraphParams = @{ Method = "GET" URI = "$GraphURI/deviceAppManagement/mobileAppConfigurations?`$filter=microsoft.graph.androidManagedStoreAppConfiguration/appSupportsOemConfig%20eq%20true" Headers = $GraphHeader } $GraphRequest = Invoke-RestMethod @GraphParams -ErrorAction Stop $All_GraphRequest = @() $All_GraphRequest += $GraphRequest while ($GraphRequest.'@odata.nextLink') { $GraphRequest_NextLink = @{ Method = "GET" URI = $GraphRequest.'@odata.nextLink' Headers = $GraphHeader ContentType = "application/JSON" } $GraphRequest = Invoke-RestMethod @GraphRequest_NextLink -ErrorAction Stop $All_GraphRequest += $GraphRequest } } catch { $Error[0] Throw "The Microsoft Graph Query Failed," } Switch ($Type) { Default { $All_GraphRequest | Select-Object -ExpandProperty Value } FilterQuery { $All_GraphRequest | Select-Object -ExpandProperty Value | Where-Object id -Match $($PSBoundParameters.FilterID) } } } } Function Import-OEMConfigProfile { [CmdletBinding()] param ( [ValidateSet('Object', 'File')] $Type, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion" ) DynamicParam { switch ($Type) { File { #If the Import Param is used, Create the File Param $FileAttribute = New-Object System.Management.Automation.ParameterAttribute $FileAttribute.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom FileAttribute attribute $attributeCollection.Add($FileAttribute) #add our paramater specifying the attribute collection $File = New-Object System.Management.Automation.RuntimeDefinedParameter('File', [string], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('File', $File) return $paramDictionary } Object { $ObjectAttrib = New-Object System.Management.Automation.ParameterAttribute $ObjectAttrib.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom ObjectAttrib attribute $attributeCollection.Add($ObjectAttrib) #add our paramater specifying the attribute collection $ImportObject = New-Object System.Management.Automation.RuntimeDefinedParameter('ImportObject', [Object] , $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('ImportObject', $ImportObject) return $paramDictionary } } } begin { #If the File Param is used, Test the Path to make sure its accessible, If not throw an error. If it does exist set the JSONImport Param to the AttributeValue IF ($PSBoundParameters.File) { IF (-not (Test-Path -Path $PSBoundParameters.File)) { Throw "Unable to locate $PSBoundParameters.File" } else { $JSONImport = $PSBoundParameters.File } } IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } $GraphHeader = @{Authorization = "Bearer $($BGUAccessToken.AccessToken)" } } #Process The Function Process { switch ($Type) { File { $ImportBody = Get-Content $JSONImport | ConvertFrom-Json | Select-Object -Property * -ExcludeProperty Version, LastModifiedDateTime, CreatedDateTime, id, supportsScopeTags | ConvertTo-Json -Depth 10 } Object { $ImportBody = $PSBoundParameters.ImportObject | Select-Object -Property * -ExcludeProperty Version, CreatedDateTime, id, supportsScopeTags, lastModifiedDateTime | ConvertTo-Json -Depth 10 } } $GraphImportParams = @{ Method = "POST" URI = "$GraphURI/deviceAppManagement/mobileAppConfigurations" BODY = $ImportBody Headers = $GraphHeader CONTENTTYPE = "application/Json" } Invoke-RestMethod @GraphImportParams } } function Export-OEMConfigProfile { param( [Parameter(Mandatory = $True)] $PolicyID, [ValidateSet('Object', 'File')] [Parameter(Mandatory = $True)] $Type, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion" ) DynamicParam { #If the Import Param is used, Create the File Param switch ($Type) { File { $FileAttribute = New-Object System.Management.Automation.ParameterAttribute $FileAttribute.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom FileAttribute attribute $attributeCollection.Add($FileAttribute) #add our paramater specifying the attribute collection $ExportLocation = New-Object System.Management.Automation.RuntimeDefinedParameter('ExportLocation', [string], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('ExportLocation', $ExportLocation) return $paramDictionary } } } begin { IF ($PSBoundParameters.ExportLocation) { $ExportLocation = $PSBoundParameters.ExportLocation } IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } $GraphHeader = @{Authorization = "Bearer $($BGUAccessToken.AccessToken)" } } Process { $GraphObjectParams = @{ METHOD = "GET" URI = "$GraphURI/deviceAppManagement/mobileAppConfigurations/$($PolicyID)" HEADERS = $GraphHeader } $export_obj = Invoke-RestMethod @GraphObjectParams if ($export_obj) { switch ($Type) { Object { $export_obj } File { # Export The Base Admin Template ConvertTo-Json $export_obj -Depth 10 | Out-File "$ExportLocation\$(($export_obj.displayName)).json" -Encoding ascii -Force } } } } } function Copy-OEMConfigProfile { param( [string] [Parameter(Mandatory = $True)] $PolicyID, [Parameter(Mandatory = $True)] [ValidateSet('Copy', 'Test', 'PreProd', 'Dev', 'Prod', 'Pilot', 'Custom')] $Prefix, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion" ) DynamicParam { #If the Import Param is used, Create the File Param switch ($Prefix) { Custom { $CustomAttrib = New-Object System.Management.Automation.ParameterAttribute $CustomAttrib.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom CustomAttrib attribute $attributeCollection.Add($CustomAttrib) #add our paramater specifying the attribute collection $CustomPrefix = New-Object System.Management.Automation.RuntimeDefinedParameter('CustomPrefix', [string], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('CustomPrefix', $CustomPrefix) return $paramDictionary } } } begin { IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } switch ($Prefix) { Custom { $PolicyPrefix = $PSBoundParameters.CustomPrefix.ToUpper() } Default { $PolicyPrefix = $Prefix.ToUpper() } } } process { Write-Output "Object iD: $($PolicyID)" $BaseObject = Export-OEMConfigProfile -Type Object $PolicyID $BaseObject.displayName = "$PolicyPrefix-$($BaseObject.displayName)" Import-OEMConfigProfile -Type Object -ImportObject $BaseObject } } #endregion Configuration Profiles #region OEMConfig Function Get-EnrolmentConfiguration { <# .SYNOPSIS This function is used to get Enrolment Status Page from the GraphAPI Associated with your connected tenant. .DESCRIPTION This function is used to get Enrolment Status Page from the GraphAPI Associated with your connected tenant. It is possible to filter these by using -Type FilterQuery -FilterID <policyID>, you can also user Where-Object to filter these. .EXAMPLE PS C:\> Get-EnrolmentConfiguration This will return all of the policies within your connected tenant .EXAMPLE PS C:\> Get-EnrolmentConfiguration -Type FilterQuery -FilterID <PolicyID> This will return the single policy for the ID you specify .INPUTS -Type : Used when you want to specify if you want to Filter the ID. -FilterID : The ID of the Policy .OUTPUTS .NOTES This covers all policies, excluding the settings catalogue, Administrative Templates and Endpoint Security Profiles #> [CmdletBinding()] param ( [ValidateSet('All', 'FilterQuery')] $Type, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion" ) DynamicParam { #If the Import Param is used, Create the File Param switch ($Type) { FilterQuery { $FAttrib = New-Object System.Management.Automation.ParameterAttribute $FAttrib.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom FileAttribute attribute $attributeCollection.Add($FAttrib) #add our paramater specifying the attribute collection $FilterID = New-Object System.Management.Automation.RuntimeDefinedParameter('FilterID', [string], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('FilterID', $FilterID) return $paramDictionary } } } begin { IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } $GraphHeader = @{Authorization = "Bearer $($BGUAccessToken.AccessToken)" } } #Process The Function Process { try { $GraphParams = @{ Method = "GET" URI = "$GraphURI/deviceManagement/deviceEnrollmentConfigurations" Headers = $GraphHeader } $GraphRequest = Invoke-RestMethod @GraphParams -ErrorAction Stop $All_GraphRequest = @() $All_GraphRequest += $GraphRequest while ($GraphRequest.'@odata.nextLink') { $GraphRequest_NextLink = @{ Method = "GET" URI = $GraphRequest.'@odata.nextLink' Headers = $GraphHeader ContentType = "application/JSON" } $GraphRequest = Invoke-RestMethod @GraphRequest_NextLink -ErrorAction Stop $All_GraphRequest += $GraphRequest } } catch { $Error[0] Throw "The Microsoft Graph Query Failed," } Switch ($Type) { Default { $All_GraphRequest | Select-Object -ExpandProperty Value } FilterQuery { $All_GraphRequest | Select-Object -ExpandProperty Value | Where-Object id -Match $($PSBoundParameters.FilterID) } } } } Function Import-EnrolmentConfiguration { [CmdletBinding()] param ( [ValidateSet('Object', 'File')] $Type, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion" ) DynamicParam { switch ($Type) { File { #If the Import Param is used, Create the File Param $FileAttribute = New-Object System.Management.Automation.ParameterAttribute $FileAttribute.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom FileAttribute attribute $attributeCollection.Add($FileAttribute) #add our paramater specifying the attribute collection $File = New-Object System.Management.Automation.RuntimeDefinedParameter('File', [string], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('File', $File) return $paramDictionary } Object { $ObjectAttrib = New-Object System.Management.Automation.ParameterAttribute $ObjectAttrib.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom ObjectAttrib attribute $attributeCollection.Add($ObjectAttrib) #add our paramater specifying the attribute collection $ImportObject = New-Object System.Management.Automation.RuntimeDefinedParameter('ImportObject', [Object] , $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('ImportObject', $ImportObject) return $paramDictionary } } } begin { #If the File Param is used, Test the Path to make sure its accessible, If not throw an error. If it does exist set the JSONImport Param to the AttributeValue IF ($PSBoundParameters.File) { IF (-not (Test-Path -Path $PSBoundParameters.File)) { Throw "Unable to locate $PSBoundParameters.File" } else { $JSONImport = $PSBoundParameters.File } } IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } $GraphHeader = @{Authorization = "Bearer $($BGUAccessToken.AccessToken)" } } #Process The Function Process { switch ($Type) { File { $ImportBody = Get-Content $JSONImport | ConvertFrom-Json | Select-Object -Property * -ExcludeProperty Version, LastModifiedDateTime, CreatedDateTime, id, supportsScopeTags, Priority | ConvertTo-Json -Depth 10 } Object { $ImportBody = $PSBoundParameters.ImportObject | Select-Object -Property * -ExcludeProperty Version, CreatedDateTime, id, supportsScopeTags, lastModifiedDateTime, Priority | ConvertTo-Json -Depth 10 } } $GraphImportParams = @{ Method = "POST" URI = "$GraphURI/deviceManagement/deviceEnrollmentConfigurations" BODY = $ImportBody Headers = $GraphHeader CONTENTTYPE = "application/Json" } Invoke-RestMethod @GraphImportParams } } function Export-EnrolmentConfiguration { param( [Parameter(Mandatory = $True)] $PolicyID, [ValidateSet('Object', 'File')] [Parameter(Mandatory = $True)] $Type, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion" ) DynamicParam { #If the Import Param is used, Create the File Param switch ($Type) { File { $FileAttribute = New-Object System.Management.Automation.ParameterAttribute $FileAttribute.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom FileAttribute attribute $attributeCollection.Add($FileAttribute) #add our paramater specifying the attribute collection $ExportLocation = New-Object System.Management.Automation.RuntimeDefinedParameter('ExportLocation', [string], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('ExportLocation', $ExportLocation) return $paramDictionary } } } begin { IF ($PSBoundParameters.ExportLocation) { $ExportLocation = $PSBoundParameters.ExportLocation } IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } $GraphHeader = @{Authorization = "Bearer $($BGUAccessToken.AccessToken)" } } Process { $GraphObjectParams = @{ METHOD = "GET" URI = "$GraphURI/deviceManagement/deviceEnrollmentConfigurations/$($PolicyID)" HEADERS = $GraphHeader } $export_obj = Invoke-RestMethod @GraphObjectParams if ($export_obj) { switch ($Type) { Object { $export_obj } File { # Export The Base Admin Template ConvertTo-Json $export_obj -Depth 10 | Out-File "$ExportLocation\$(($export_obj.displayName)).json" -Encoding ascii -Force } } } } } function Copy-EnrolmentConfiguration { param( [string] [Parameter(Mandatory = $True)] $PolicyID, [Parameter(Mandatory = $True)] [ValidateSet('Copy', 'Test', 'PreProd', 'Dev', 'Prod', 'Pilot', 'Custom')] $Prefix, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion" ) DynamicParam { #If the Import Param is used, Create the File Param switch ($Prefix) { Custom { $CustomAttrib = New-Object System.Management.Automation.ParameterAttribute $CustomAttrib.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom CustomAttrib attribute $attributeCollection.Add($CustomAttrib) #add our paramater specifying the attribute collection $CustomPrefix = New-Object System.Management.Automation.RuntimeDefinedParameter('CustomPrefix', [string], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('CustomPrefix', $CustomPrefix) return $paramDictionary } } } begin { IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } switch ($Prefix) { Custom { $PolicyPrefix = $PSBoundParameters.CustomPrefix.ToUpper() } Default { $PolicyPrefix = $Prefix.ToUpper() } } } process { Write-Output "Object iD: $($PolicyID)" $BaseObject = Export-EnrolmentConfiguration -Type Object $PolicyID $BaseObject.displayName = "$PolicyPrefix-$($BaseObject.displayName)" Import-EnrolmentConfiguration -Type Object -ImportObject $BaseObject } } #endregion Enrolment Configurations #region SettingsCatalog Function Get-SettingsCatalog { <# .SYNOPSIS This function is used to get Settings Catalog policies from the GraphAPI Associated with your connected tenant. .DESCRIPTION This function is used to get Settings Catalog policies from the GraphAPI Associated with your connected tenant. It is possible to filter these by using -Type FilterQuery -FilterID <policyID>, you can also user Where-Object to filter these. .EXAMPLE PS C:\> Get-SettingsCatalog This will return all of the policies within your connected tenant .EXAMPLE PS C:\> Get-SettingsCatalog -Type FilterQuery -FilterID <PolicyID> This will return the single policy for the ID you specify .INPUTS -Type : Used when you want to specify if you want to Filter the ID. -FilterID : The ID of the Policy .OUTPUTS Sample: createdDateTime : 2022-02-23T16:48:07.7797091Z creationSource : description : lastModifiedDateTime : 2022-02-23T16:48:07.7797091Z name : SettingsCatalog_Policy platforms : windows10 roleScopeTagIds : {0} settingCount : 6 technologies : mdm id : <GUID> templateReference : @{templateId=; templateFamily=none; templateDisplayName=; templateDisplayVersion=} .NOTES #> [CmdletBinding()] param ( [ValidateSet('All', 'FilterQuery')] $Type, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion" ) DynamicParam { #If the Import Param is used, Create the File Param switch ($Type) { FilterQuery { $FAttrib = New-Object System.Management.Automation.ParameterAttribute $FAttrib.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom FileAttribute attribute $attributeCollection.Add($FAttrib) #add our paramater specifying the attribute collection $FilterID = New-Object System.Management.Automation.RuntimeDefinedParameter('FilterID', [string], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('FilterID', $FilterID) return $paramDictionary } } } begin { IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } $GraphHeader = @{Authorization = "Bearer $($BGUAccessToken.AccessToken)" } } #Process The Function Process { try { $GraphParams = @{ Method = "GET" URI = "$GraphURI/deviceManagement/configurationPolicies" Headers = $GraphHeader } $GraphRequest = Invoke-RestMethod @GraphParams -ErrorAction Stop $All_GraphRequest = @() $All_GraphRequest += $GraphRequest while ($GraphRequest.'@odata.nextLink') { $GraphRequest_NextLink = @{ Method = "GET" URI = $GraphRequest.'@odata.nextLink' Headers = $GraphHeader ContentType = "application/JSON" } $GraphRequest = Invoke-RestMethod @GraphRequest_NextLink -ErrorAction Stop $All_GraphRequest += $GraphRequest } } catch { $Error[0] Throw "The Microsoft Graph Query Failed." } Switch ($Type) { Default { $All_GraphRequest | Select-Object -ExpandProperty Value } FilterQuery { $All_GraphRequest | Select-Object -ExpandProperty Value | Where-Object id -Match $($PSBoundParameters.FilterID) } } } } function Get-SettingsCatalog_Settings { <# .SYNOPSIS This function is used to get Settings Catalog policy settings from the GraphAPI Associated with your connected tenant. .DESCRIPTION This function is used to get Settings Catalog policy settings from the GraphAPI Associated with your connected tenant. This function accepts the Object input from Get-SettingsCatalog .EXAMPLE PS C:\> Get-SettingsCatalog_Settings -InputObject (Get-SettingsCatalog -Type FilterQuery -FilterID <PolicyID>) This will return all of the policy settings for that SettingsCatalog .INPUTS -InputObject : The object output of Get-SettingsCatalog .OUTPUTS Sample: id settingInstance -- --------------- 0 @{@odata.type=#microsoft.graph.deviceManagementConfigurationChoiceSettingInstance; settingDefinitionId=device_vendor_msft_policy_config_admx_datacollection_commercialidpolicy; settingInstanceTem... 1 @{@odata.type=#microsoft.graph.deviceManagementConfigurationChoiceSettingInstance; settingDefinitionId=device_vendor_msft_policy_config_system_allowdevicenameindiagnosticdata; settingInstanceTem... 2 @{@odata.type=#microsoft.graph.deviceManagementConfigurationChoiceSettingInstance; settingDefinitionId=device_vendor_msft_policy_config_system_allowtelemetry; settingInstanceTemplateReference=; ... .NOTES #> param( [Parameter(Mandatory = $true)] $InputObject, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion" ) begin { IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } $GraphHeader = @{Authorization = "Bearer $($BGUAccessToken.AccessToken)" } } Process { $GraphParams = @{ METHOD = "GET" URI = "$GraphURI/deviceManagement/configurationPolicies('$($InputObject.id)')/settings" HEADERS = $GraphHeader } $GraphRequest = Invoke-RestMethod @GraphParams -ErrorAction Stop $All_GraphRequest = @() $All_GraphRequest += $GraphRequest while ($GraphRequest.'@odata.nextLink') { $GraphRequest_NextLink = @{ Method = "GET" URI = $GraphRequest.'@odata.nextLink' Headers = $GraphHeader ContentType = "application/JSON" } $GraphRequest = Invoke-RestMethod @GraphRequest_NextLink -ErrorAction Stop $All_GraphRequest += $GraphRequest } $All_GraphRequest | Select-Object -ExpandProperty Value } } Function Import-SettingsCatalog { [CmdletBinding()] param ( [ValidateSet('Object', 'File')] $Type, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion" ) DynamicParam { switch ($Type) { File { #If the Import Param is used, Create the File Param $FileAttribute = New-Object System.Management.Automation.ParameterAttribute $FileAttribute.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom FileAttribute attribute $attributeCollection.Add($FileAttribute) #add our paramater specifying the attribute collection $File = New-Object System.Management.Automation.RuntimeDefinedParameter('File', [string], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('File', $File) return $paramDictionary } Object { $ObjectAttrib = New-Object System.Management.Automation.ParameterAttribute $ObjectAttrib.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom ObjectAttrib attribute $attributeCollection.Add($ObjectAttrib) #add our paramater specifying the attribute collection $ImportObject = New-Object System.Management.Automation.RuntimeDefinedParameter('ImportObject', [Object], $attributeCollection) $ImportObject_Settings = New-Object System.Management.Automation.RuntimeDefinedParameter('ImportObject_Settings', [Object], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('ImportObject', $ImportObject) $paramDictionary.Add('ImportObject_Settings', $ImportObject_Settings) return $paramDictionary } } } begin { #If the File Param is used, Test the Path to make sure its accessible, If not throw an error. If it does exist set the Import_File Param to the AttributeValue IF ($PSBoundParameters.File) { IF (-not (Test-Path -Path $PSBoundParameters.File)) { Throw "Unable to locate $PSBoundParameters.File" } else { $Import_File = $PSBoundParameters.File } } IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } $GraphHeader = @{Authorization = "Bearer $($BGUAccessToken.AccessToken)" } } #Process The Function Process { switch ($Type) { File { $File_Info = Get-Item $Import_File | Select-Object -Property * $ImportSettingsFile = Join-Path -Path $File_Info.DirectoryName -ChildPath ($File_Info.BaseName + "_settings.json") if (Test-Path -Path $ImportSettingsFile) { $Settings = (ConvertFrom-Json -InputObject (Get-Content $ImportSettingsFile -Raw)) } $BasePolicy = Get-Content $Import_File | ConvertFrom-Json | Select-Object -Property * -ExcludeProperty CreatedDateTime, lastModifiedDateTime, id, settingcount, CreatedDateTime, id, supportsScopeTags, roleScopeTagIds, creationsource } Object { $BasePolicy = $PSBoundParameters.ImportObject | Select-Object -Property * -ExcludeProperty CreatedDateTime, lastModifiedDateTime, id, settingcount, CreatedDateTime, id, supportsScopeTags, roleScopeTagIds, creationsource $Settings = $PSBoundParameters.ImportObject_Settings } } $BasePolicy | Add-Member -MemberType NoteProperty -Name settings -Value @() $BasePolicy.settings += $Settings $ImportParams = @{ Method = "POST" URI = "$GraphURI/deviceManagement/configurationPolicies" BODY = ($BasePolicy | ConvertTo-Json -Depth 20) Headers = $GraphHeader CONTENTTYPE = "application/Json" } ($BasePolicy | ConvertTo-Json -Depth 20) | Set-Clipboard Invoke-RestMethod @ImportParams } } function Export-SettingsCatalog { param( [Parameter(Mandatory = $True)] $PolicyID, [ValidateSet('Object', 'File')] [Parameter(Mandatory = $True)] $Type, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion" ) DynamicParam { #If the Import Param is used, Create the File Param switch ($Type) { File { $FileAttribute = New-Object System.Management.Automation.ParameterAttribute $FileAttribute.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom FileAttribute attribute $attributeCollection.Add($FileAttribute) #add our parameter specifying the attribute collection $ExportLocation = New-Object System.Management.Automation.RuntimeDefinedParameter('ExportLocation', [string], $attributeCollection) $ImportObject_Settings = New-Object System.Management.Automation.RuntimeDefinedParameter('ImportObject_Settings', [Object], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('ExportLocation', $ExportLocation) return $paramDictionary } Object { $ObjectAttrib = New-Object System.Management.Automation.ParameterAttribute $ObjectAttrib.Mandatory = $false #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom ObjectAttrib attribute $attributeCollection.Add($ObjectAttrib) #add our paramater specifying the attribute collection $IncludeSettings = New-Object System.Management.Automation.RuntimeDefinedParameter('IncludeSettings', [bool], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('IncludeSettings', $IncludeSettings) return $paramDictionary } } } begin { IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } IF ($PSBoundParameters.ExportLocation) { $ExportLocation = $PSBoundParameters.ExportLocation } IF ($PSBoundParameters.IncludeSettings) { $IncludeSettings = $PSBoundParameters.IncludeSettings } $GraphHeader = @{Authorization = "Bearer $($BGUAccessToken.AccessToken)" } } Process { $GraphObjectParams = @{ METHOD = "GET" URI = "$GraphURI/deviceManagement/configurationPolicies/$($PolicyID)" HEADERS = $GraphHeader } $export_obj = Invoke-RestMethod @GraphObjectParams if ($export_obj) { switch ($Type) { Object { Switch ($IncludeSettings) { True { $export_obj | Add-Member -MemberType NoteProperty -Name settings -Value @() $export_obj.settings += Get-SettingsCatalog_Settings -InputObject $export_obj } } $export_obj } File { # Export The Base Policy ConvertTo-Json $export_obj -Depth 20 | Out-File "$ExportLocation\$(($export_obj.name)).json" -Encoding ascii -Force "Exported $($export_obj.name) to $ExportLocation\$(($export_obj.name)).json" # Export the settings from the Policy ConvertTo-Json (Get-SettingsCatalog_Settings -InputObject $export_obj) -Depth 20 | Out-File "$ExportLocation\$($export_obj.name)_Settings.json" -Encoding ascii -Force "Exported $($export_obj.name) settings to $ExportLocation\$(($export_obj.name))_Settings.json" } } } } } function Copy-SettingsCatalog { param( [string] [Parameter(Mandatory = $True)] $PolicyID, [Parameter(Mandatory = $True)] [ValidateSet('Copy', 'Test', 'PreProd', 'Dev', 'Prod', 'Pilot', 'Custom')] $Prefix, [Parameter(DontShow = $true)] [string] $MsGraphVersion = "beta", [Parameter(DontShow = $true)] [string] $MsGraphHost = "graph.microsoft.com", [Parameter(DontShow = $true)] $GraphURI = "https://$MSGraphHost/$MsGraphVersion" ) DynamicParam { #If the Import Param is used, Create the File Param switch ($Prefix) { Custom { $CustomAttrib = New-Object System.Management.Automation.ParameterAttribute $CustomAttrib.Mandatory = $true #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] #add custom CustomAttrib attribute $attributeCollection.Add($CustomAttrib) #add our paramater specifying the attribute collection $CustomPrefix = New-Object System.Management.Automation.RuntimeDefinedParameter('CustomPrefix', [string], $attributeCollection) #expose the name of our parameter $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('CustomPrefix', $CustomPrefix) return $paramDictionary } } } begin { IF (-Not ($BGUAccessToken)) { Throw "You must first obtain an access token by running Get-BGUAccessToken, please obtain a token and retry this action" } elseif ($BGUAccessToken.ExpiresOn.LocalDateTime -LT $(Get-Date)) { Throw "You're access token expired $($BGUAccessToken.ExpiresOn.LocalDateTime), you must obtain a new access token by running Get-BGUAccessToken." } switch ($Prefix) { Custom { $PolicyPrefix = $PSBoundParameters.CustomPrefix.ToUpper() } Default { $PolicyPrefix = $Prefix.ToUpper() } } } process { Write-Output "Object iD: $($PolicyID)" $BaseObject = Export-SettingsCatalog -Type Object $PolicyID $BaseObject.name = "$PolicyPrefix-$($BaseObject.name)" $BaseObject_Settings = Get-SettingsCatalog_Settings -InputObject $BaseObject Import-SettingsCatalog -Type Object -ImportObject $BaseObject -ImportObject_Settings $BaseObject_Settings } } #endregion Settings Catalog Export-ModuleMember -Alias * -Function * |