I’m sure most if not all of you have a test tenant (never test in production) for new policies, features etc. What happens when you then want to push this change out to live (or even to multiple customers)? You either have to JSON the policy and run the script, use a backup and restore option, or worst case manually create the policy by hand.
Lucky for you, I have developed an update to my copy script which will now copy the policy across tenants
Updated – 24/02/2023
Version 6.0 released with a significant performance improvement
Updated – 27/01/2023
Version 5.0 just released with:
- Support for automation
- Support for Graph authentication via app registration
- Added parameters for command line usage without GUI (and running in devops pipeline/runbook)
- Added ability to copy using only policy name
- Parameters for ID and Name support multiple entries comma separated
Update – 05/01/2023
Version 4.0 just released adding support for:
- Policy Sets
- Enrollment Configuration Policies
- Device Categories
- Device Filters
- Branding Profiles
- Admin Approvals
- Intune Terms
- Custom roles
Update 22/12/2022 – Version 3.2 supports Windows 365 Provisioning Policies and User Settings
Update 02/12/2022 – Version 3.1 now supports new Winget Store applications (and re-written to use Graph SDK)
Update 16/09/2022 – Version 3.0 now released with added support for Applocker policies, Imported ADMX, Conditional Access, Proactive Remediations and AAD Groups
UPDATE 28/08/2022 – Version 2.0 now released which supports multiple policy selection (Ctrl-Click) to fully migrate environments
The script can be found here
Or grab from PS Gallery:
Install-Script -Name copy-intune-policy-crosstenant
As with the previous script, when you run, it will prompt for your credentials and then list all of the configured policies in the tenant in a nice table:
Simply select the policy, click the OK button and it will prompt for credentials for the destination tenant and do it’s magic.
To avoid any naming issues, the new policy will be called “Copy of” Policyname (just in case it’s an updated policy and you want to run side by side)
I hope this is of use, as always, feel free to comment below
never prompts for login WARNING: Unable to find type [Microsoft.Graph.PowerShell.Authentication.Utilities.DependencyAssemblyResolver].
and get that error?
What version of PowerShell are you running?
Very nice!
It should be perfect if we had choice or by default that copied conditional access are in audit mode to reduce possible problems.
THank you
Im using interactive connection. I reverted to the earlier version 6.0.14 and now it works again prompting me for source tenant credentails before showing me the GUI where I can select the policies I need to transfer.
I just installed the new version with the force parameter to install over the previous version that worked fine for me.
With the new version i get this error. Have tried to close all ps sessions and have even rebooted machine.
It doesnt prompt me for source tenant credentials. Just gives error messages and then prompts me for destination tenant creds.
PS C:\WINDOWS\system32> copy-intune-policy-crosstenant
Transcript started, output file is C:\Users\ADM_TO~1\AppData\Local\Temp\intune-20230829T1340038429.log
Installing Microsoft Graph modules if required (current user scope)
Installing Microsoft Graph modules if required (current user scope)
Microsoft Graph Authentication Already Installed
Microsoft Graph Corporate Management Already Installed
Microsoft Graph Groups Already Installed
Microsoft Graph DeviceManagement Already Installed
Microsoft Graph Identity SignIns Already Installed
Disconnect-MgGraph : No application to sign out from.
At C:\Program Files\WindowsPowerShell\Scripts\copy-intune-policy-crosstenant.ps1:208 char:1
+ Disconnect-MgGraph
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [Disconnect-MgGraph], ArgumentException
+ FullyQualifiedErrorId : Microsoft.Graph.PowerShell.Authentication.Cmdlets.DisconnectMgGraph
Connect-ToGraph : Cannot process argument transformation on parameter ‘scopes’. Cannot convert value to type System.Str
ing.
At C:\Program Files\WindowsPowerShell\Scripts\copy-intune-policy-crosstenant.ps1:3892 char:29
+ … aph -Scopes Policy.ReadWrite.ConditionalAccess, CloudPC.ReadWrite.All …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Connect-ToGraph], ParameterBindingArgumentTransformationException
+ FullyQualifiedErrorId : ParameterArgumentTransformationError,Connect-ToGraph
No parameters passed, grabbing all profiles
Get-MgGroup : Authentication needed, call Connect-MgGraph.
At C:\Program Files\WindowsPowerShell\Scripts\copy-intune-policy-crosstenant.ps1:1164 char:13
+ Get-MgGroup | Where-Object OnPremisesSyncEnabled -NE true
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-MgGroup_List], AuthenticationException
+ FullyQualifiedErrorId : Microsoft.Graph.PowerShell.Cmdlets.GetMgGroup_List
No parameters detected, displaying UI
Disconnect-MgGraph : No application to sign out from.
At C:\Program Files\WindowsPowerShell\Scripts\copy-intune-policy-crosstenant.ps1:4356 char:9
+ Disconnect-MgGraph
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [Disconnect-MgGraph], ArgumentException
+ FullyQualifiedErrorId : Microsoft.Graph.PowerShell.Authentication.Cmdlets.DisconnectMgGraph
Connecting to destination tenant
Hi,
Are you using an app reg or interactive connection? Are you specifying any parameters?
You’re a wizard and appreciate all your assistance for us MSP folk.
I’m also having the same issue as @MikeBobin with the authentication loop. I’ve closed all PS windows and reran the script multiple times and same issue. I did notice an error for the MS Graph Identify Signins showing “Disconnect-MgGraph : No application to sign out from.”. Not sure if this is related as you said MS Graph throws errors often.
Can you check which version of Microsoft.Graph.Authentication you have installed? I wonder if the v2 might behave better
Hi, Trying to use the latest script now, logging in with a Global admin but just getting stuck in an authentication loop. Tried a tenancy with MFA and one without. Any ideas?
Thanks
Hi,
Try closing all PowerShell windows and then re-launching, I think it’s the authentication mechanism that does it, happens to me sometimes too
And the last CA Policy giving me trouble when copying to another tenant was targeted to only one app “Sharepoint Online”. When I changed the policy to all apps it worked.
I’ve just released a new version which should resolve all of these issues
Another CA Policy that failed to import was set to “All cloud apps” excluding the app “Microsoft Intune”. When I removed the exclution the copy worked.
One of the CA Policies I couldnt copy to another tenant had the grant setting of “Require authentication strength”
Maybe the script does not support that
Good question, I’ll do some testing and if it doesn’t, I’ll fix it 🙂
I use interactive and my account can create CA Policies.
Now I have tried another destination tenant, and it creates some but not all CA Policies. I will look deeper into this and get back
For some reason I cannot copy any CA Policy to another tenant
All CA Policies in the script gets this error.
Invoke-MgGraphRequest : POST https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies
HTTP/1.1 403 Forbidden
Transfer-Encoding: chunked
Vary: Accept-Encoding
Strict-Transport-Security: max-age=31536000
request-id: 06e02b89-bd1f-453b-93e7-e63816f5e073
client-request-id: 06e02b89-bd1f-453b-93e7-e63816f5e073
x-ms-ags-diagnostic: {“ServerInfo”:{“DataCenter”:”West Europe”,”Slice”:”E”,”Ring”:”5″,”ScaleUnit”:”004″,”RoleInstance”:”AM2PEPF0000BE59″}}
Cache-Control: no-cache
Date: Tue, 16 May 2023 08:57:44 GMT
Content-Encoding: gzip
Content-Type: application/json
{“error”:{“code”:”AccessDenied”,”message”:”You cannot perform the requested operation, required scopes are missing in the token.”,”innerError”:{“date”:”2023-05-16T08:57:45″,”request-id”:”06e02b89-bd1f-453b-93e7-e63816f5e073″,”cli
ent-request-id”:”06e02b89-bd1f-453b-93e7-e63816f5e073″}}}
At C:\Program Files\WindowsPowerShell\Scripts\copy-intune-policy-crosstenant.ps1:4171 char:24
+ … $null = Invoke-MgGraphRequest -Method POST -uri $uri -Body $body …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (Method: POST, R…ication/json
}:HttpRequestMessage) [Invoke-MgGraphRequest], HttpResponseException
+ FullyQualifiedErrorId : InvokeGraphHttpResponseException,Microsoft.Graph.PowerShell.Authentication.Cmdlets.InvokeMgGraphRequest
Hi,
Are you using an app registration or interactive login?
If it’s an app reg, make sure it has this API permission:
Policy.ReadWrite.ConditionalAccess
If it’s interactive, make sure your user account has permissions to create a conditional access policy
HI Getting the following error copying Config Profile.
The profile Name copies but the settings are not there.
PS>TerminatingError(Get-GroupPolicyConfigurationsDefinitionValues): “Cannot process argument transformation on parameter ‘GroupPolicyConfigurationID’. Cannot convert value to type System.String.”
Get-GroupPolicyConfigurationsDefinitionValues : Cannot process argument transformation on parameter
‘GroupPolicyConfigurationID’. Cannot convert value to type System.String.
At C:\Program Files\WindowsPowerShell\Scripts\copy-intune-policy-crosstenant.ps1:4184 char:136
+ … pPolicyConfigurationsDefinitionValues -GroupPolicyConfigurationID $id
+ ~~~
+ CategoryInfo : InvalidData: (:) [Get-GroupPolicy…efinitionValues],
ParameterBindingArgumentTransformationException
+ FullyQualifiedErrorId : ParameterArgumentTransformationError,Get-GroupPolicyConfigurationsDefinitionValues
Get-GroupPolicyConfigurationsDefinitionValues : Cannot process argument transformation on parameter
‘GroupPolicyConfigurationID’. Cannot convert value to type System.String.
At C:\Program Files\WindowsPowerShell\Scripts\copy-intune-policy-crosstenant.ps1:4184 char:136
+ … pPolicyConfigurationsDefinitionValues -GroupPolicyConfigurationID $id
+ ~~~
+ CategoryInfo : InvalidData: (:) [Get-GroupPolicy…efinitionValues], ParameterBindingArgumentTransforma
tionException
+ FullyQualifiedErrorId : ParameterArgumentTransformationError,Get-GroupPolicyConfigurationsDefinitionValues
ClientId : 14d82eec-204b-4c2f-b7e8-296a70dab67e
TenantId : 5eb5d2dd-1bf2-40df-956a-5cfe30cb80a4
CertificateThumbprint :
Scopes : {CloudPC.ReadWrite.All, DeviceManagementApps.ReadWrite.All,
DeviceManagementConfiguration.ReadWrite.All, DeviceManagementManagedDevices.ReadWrite.All…}
AuthType : Delegated
AuthProviderType : InteractiveAuthenticationProvider
CertificateName :
Hi, I’ve just updated the script which should fix this
Hi Andrew
I am just authenticating with a GA User for both steps.
shaun
Would you be able to share the Connect-MgGraph scopes? I wonder if the CA one is missing
Andrew
Further to this i managed to get it to work on a new machine after downloading the script again
However, when copying CA policies i get an HTTP 403 forbidden error when trying to export to the destination tenant
thanks
Glad you are making progress. How are you authenticating on each tenant? User or App reg?
Hi Andrew
Just revisiting this.. a few things I noticed
1. Seems to occasionally loop on authentication
2. Also seems to keep telling me I need to update my version when i have the latest version from Git Hub
3. I also noticed that conditional access Policies didn’t show up as an option to copy
Thanks and great work !
Thanks Andrew ,
I have just tested this and it seems to throw the authentication into a loop .
I was testing this with ISE/VSCODE and Commandline
Thanks
Thanks Andrew
Had some issues with the latest script not returning any conditional access Policies? Also tells me the script needs to be updated. even though using the latest version
Thanks
CA policies should be sorted now.
Are you running in ISE/VSCode or direct in commandline?
Hi Andrew, first off great script.
I have submitted a pull request to the script as I also had issue with settings catalog policies where it only copies across the first 25 settings due to paging. This seemed to be because the $settings variable containing the next link is overwritten. I also noticed that the replace command was blanking out the next link too.
Hi Mark,
Thank you, well spotted. That’s merged now and I’ve updated the PSGallery version as well
Hi Andrew,
We encountered a slight issue with settings catalogs in particular. If the policy has a large number of settings configured after a certain point the settings in the policies where not copied over. After some investigation we found that it was due to paging in Microsoft graph and in particular the @odata.nextlink value storing the next ‘batch’ of settings in that policy that we needed to request and then combine with the original request. We overcome by injecting the below code on the getpolicyjson command.
$policynextlink = $settings.”@odata.nextlink”
while ($policynextlink -ne $null)
{
$nextsettings = (Invoke-MgGraphRequest -Uri $policynextlink -Method Get -OutputType PSObject).value
$policynextlink = $nextsettings.”@odata.nextLink”
$settings += $nextsettings
}
Hi Jordan,
Thank you, paging can be such a pain!
I have updated this and the backup/restore script with the extra script
Hey Andrew. Great idea. Ive been trying to run it but seem to be getting stuck in a login loop. I log in and authenticate and then it just keeps asking me to pick an account and log in again. Am i doing something wrong?
Thanks
Hi Gary, what permissions does your account have? First launch will need to set Graph permissions on the tenant so will need higher permissions than subsequent runs
Thanks
Andrew
Hi Andrew,
That’s brilliant all working now thanks for the script and the work to get it sorted
Simon
Hi Andrew,
Thank you for that, I’ve tried to run the amended version but I get the below error:
Connect-MgGraph : AADSTS650053: The application ‘Microsoft Graph PowerShell’ asked for scope ‘Policy.ReadWrite.All’ that doesn’t exist on the resource
‘00000003-0000-0000-c000-000000000000’. Contact the app vendor.
Trace ID: ed8a1fad-4578-48b4-ba3b-3ab54cba3001
Correlation ID: 80de3779-5dfe-4ec6-bd77-f53d4f0c8a3d
Timestamp: 2022-11-29 13:53:02Z
At line:1144 char:1
Thanks
I’ve fixed that one, but I’m getting the same error now on Settings Catalog, I’ll let you know when I’ve worked it out
Hi Simon,
I think that should be both Settings Catalog and Conditional Access sorted now
Thanks
Morning,
When running the script, I get the below error every time after connecting to graph on the source tenant.
Welcome To Microsoft Graph!
Get-MgIdentityConditionalAccessPolicy : You cannot perform the requested operation, required scopes are missing in the token.
Also, this error when trying to copy a settings catalog
Welcome To Microsoft Graph!
Invoke-MgGraphRequest : POST https://graph.microsoft.com/beta/deviceManagement/configurationPolicies
HTTP/1.1 400 Bad Request
Transfer-Encoding: chunked
Vary: Accept-Encoding
Strict-Transport-Security: max-age=31536000
request-id: c95830b9-89c9-4676-a5d1-1b057a5e4f30
client-request-id: c95830b9-89c9-4676-a5d1-1b057a5e4f30
x-ms-ags-diagnostic: {“ServerInfo”:{“DataCenter”:”UK South”,”Slice”:”E”,”Ring”:”3″,”ScaleUnit”:”003″,”RoleInstance”:”LO2PEPF00001242″}}
Date: Tue, 29 Nov 2022 10:54:23 GMT
Content-Encoding: gzip
Content-Type: application/json
{“error”:{“code”:”ModelValidationFailure”,”message”:”The annotation ‘odata.count’ was found. This annotation is either not recognized or not expected at the current position.”,”innerError”:{“message”:”The annotation ‘odata.count’ was found. This annotation is either not
recognized or not expected at the current position.”,”date”:”2022-11-29T10:54:23″,”request-id”:”c95830b9-89c9-4676-a5d1-1b057a5e4f30″,”client-request-id”:”c95830b9-89c9-4676-a5d1-1b057a5e4f30″}}}
At C:\Users\Simon.Todd\OneDrive – One IT Services & Solutions\Desktop\Intune-Tenant-Copy.ps1:1376 char:27
+ … opypolicy = Invoke-MgGraphRequest -Uri $policyuri -Method Post -Body …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (Method: POST, R…harset=utf-8
}:HttpRequestMessage) [Invoke-MgGraphRequest], HttpResponseException
+ FullyQualifiedErrorId : InvokeGraphHttpResponseException,Microsoft.Graph.PowerShell.Authentication.Cmdlets.InvokeMgGraphRequest
Any advice would be much appreciated
Simon
Hi Simon,
I have just pushed out an updated version, can you see if that works any better please?
Thanks
Andrew
Hi Andrew Will do
thanks
Hi Andrew
Tested this out
I seem to get a bunch of the same errors compliainign about MFA
AADSTS50076: Due to a configuration change made by your administrator, or because you moved to a new
location, you must use multi-factor authentication to access ‘00000003-0000-0000-c000-000000000000’.
it goes through to list all the configurations , i can select them but only copies one
thanks
Hi Shaun, Just setup a new tenant to test this myself and it copies multiple profiles for me. Any chance you can email me (contact form will work) what’s in your policies and I’ll see if I can fully duplicate my end.
Great 🙂
I will test this out
Hey Andrew
Did you make any progress on this ? 🙂 🙂
I’ve releaed a new version using the PS Graph module for connection, can you see if that works any better?
Hi Andrew
Just some more feedback on this
I used the PS Gallery install to copy some Endpoint security policies to another tenant, I was able to copy 3 at a time. With no errors. Not sure if this was possible before
thanks
That’s good, thanks for the update. I’m looking into why the admin templates are failing
Hi Andrew
Yes, that did work, Also the output was slightly different
createdDateTime : 2022-09-23T22:10:54.0064878Z
enabled : False
configurationType : policy
id : 61401433-531b-4b3a-9e60-d47faae8f5a8
lastModifiedDateTime : 2022-09-23T22:10:54.0064878Z
@odata.context : https://graph.microsoft.com/beta/$metadata#deviceManagement/groupPolicyConfigurations('7e4ad996-
5fc7-4029-b884-9937c5802bc9′)/definitionValues/$entity
createdDateTime : 2022-10-23T23:05:03.8404742Z
enabled : False
configurationType : policy
id : 77298901-4897-4c7b-82c1-afae9b5ac2e0
lastModifiedDateTime : 2022-10-23T23:05:03.8404742Z
createdDateTime : 2022-09-22T10:22:38.333433Z
enabled : False
configurationType : policy
id : a6ea00f9-c05b-4b53-b7e3-182b4c800814
lastModifiedDateTime : 2022-09-22T10:22:38.333433Z
Ok just tested and it still only seems to copy 1 template
It’s an Admin Template
deviceManagement/groupPolicyConfigurations
43315aaa-4ab7-4477-a49b-4588a0a112a0
It’s a Settings Catalog
deviceManagement/configurationPolicies
3b84e0ba-5ea0-4547-8af7-1187ec92aece
It’s an Admin Template
deviceManagement/groupPolicyConfigurations
0c1166d1-3375-4546-8892-d2ba61640693
It’s an Admin Template
deviceManagement/groupPolicyConfigurations
1227a1cc-6bd8-43ec-b1ff-c84406ee8987
It’s an Admin Template
deviceManagement/groupPolicyConfigurations
The authtoken is null.
Checking for AzureAD module…
Connect-AzureAD : One or more errors occurred.: AADSTS50076: Due to a configuration change made by your administrator,
or because you moved to a new location, you must use multi-factor authentication to access
Can you try a multi-copy to the same tenant and see if that works? Trying to work out where it’s failing on this one
Thanks Andrew ! I will test this and report back
Hi Andrew
That was quick 🙂 Awesome
S
Just uploaded 3.0.3 which should fix it. Admin Templates are temperamental so you may see some timeout errors, but you can ignore those (I can’t find any commands to get it not to report them).
Will look at the AAD authentication issue as well, but this should get you up and running for now.
Hi Andrew
They were built in Admin Templates.. when i select more than one it seems to copy.. but then on the destination side i only have the first template i selected
It’s an Admin Template
deviceManagement/groupPolicyConfigurations
0c1166d1-3375-4546-8892-d2ba61640693
It’s an Admin Template
deviceManagement/groupPolicyConfigurations
1227a1cc-6bd8-43ec-b1ff-c84406ee8987
It’s an Admin Template
deviceManagement/groupPolicyConfigurations
Thank you, I think I’ve found the issue, just working on a fix for it
Hi Andrew
Great script and great content ( Love the weekly digest email ) 🙂
I ran into all of the above issues flagged by charles and DS McG
Ignoring the errors i was able to move 3 policies in one go that were Device restrictions and Endpoint Protection . However if they were Admin Templates then i can only do one at a time . I am running VERSION 3.0.2
Any ideas on why on what steps to take ?
Thanks
Hi Shaun,
Glad you’re finding it useful. Is it a built-in admin template or an ingested ADMX you are testing with? I had to add extra steps for admin templates so I might need to move them into a different loop. I’ll do some testing
Hi Andrew
When irun the script , it ask credential but after that i get error:
Authorization Access Token is null, please re-run authentication…
I’ve just uploaded v1.0.1 to GitHub, can you try that one please?
Is there a way to get the “apps” to come over?
I think it should be possible, I just need to make sure I can grab the files from the Azure Blob storage along with all of the other json details required
Andrew, thanks so much for everything. It’s all working now! What a huge time saver.
Excellent, glad it’s working well. Always happy to hear any suggestions or improvements as well
Thanks man. It worked that time, but then I must’ve done something else wrong because it failed, even though it DID authenticate.
Newb here. Not sure what I’m doing wrong, but the 2nd prompt for destination tenant never appears.
It returns:
It’s a Settings Catalog
deviceManagement/configurationPolicies
Get-MSGraphNextPage : Not authenticated. Please use the “Connect-MSGraph” command to authenticate.
At line:287 char:25
+ … $page = Get-MSGraphNextPage -NextLink $currentNextLink
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : AuthenticationError: (:) [Get-MSGraphNextPage], InvalidOperationException
+ FullyQualifiedErrorId : PowerShellGraphSDK_NotAuthenticated,Microsoft.Intune.PowerShellGraphSDK.PowerShellCmdlets.GetNextPage
Hi, that was an issue with the script I think, I’ve pushed out a new update, can you try it now please?
Hi Andrew,
I was testing this script and i get the following errors:
connect-azureAD : One or more errors occurred.: AADSTS50076: Due to a configuration change made by your administrator, or because
you moved to a new location, you must use multi-factor authentication to access ‘00000002-0000-0000-c000-000000000000’.
Trace ID: f895017b-daa6-49e7-9d93-744a6b583700
Correlation ID: 0c9a057c-e20e-4bb3-b9ae-2b6e96906691
Timestamp: 2022-09-28 12:45:02Z
At C:\Scripts\copy-intune-policy-crosstenant.ps1:1609 char:1
+ connect-azureAD -Credential $credential
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : AuthenticationError: (:) [Connect-AzureAD], AadAuthenticationFailedException
+ FullyQualifiedErrorId : Connect-AzureAD,Microsoft.Open.Azure.AD.CommonLibrary.ConnectAzureAD
connect-azureAD : One or more errors occurred.
At C:\Scripts\copy-intune-policy-crosstenant.ps1:1609 char:1
+ connect-azureAD -Credential $credential
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : AuthenticationError: (:) [Connect-AzureAD], AggregateException
+ FullyQualifiedErrorId : Connect-AzureAD,Microsoft.Open.Azure.AD.CommonLibrary.ConnectAzureAD
connect-azureAD : AADSTS50076: Due to a configuration change made by your administrator, or because you moved to a new location, you
must use multi-factor authentication to access ‘00000002-0000-0000-c000-000000000000’.
Trace ID: f895017b-daa6-49e7-9d93-744a6b583700
Correlation ID: 0c9a057c-e20e-4bb3-b9ae-2b6e96906691
Timestamp: 2022-09-28 12:45:02Z
At C:\Scripts\copy-intune-policy-crosstenant.ps1:1609 char:1
+ connect-azureAD -Credential $credential
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : AuthenticationError: (:) [Connect-AzureAD], AdalClaimChallengeException
+ FullyQualifiedErrorId : Connect-AzureAD,Microsoft.Open.Azure.AD.CommonLibrary.ConnectAzureAD
connect-azureAD : Response status code does not indicate success: 400 (BadRequest).
At C:\Scripts\copy-intune-policy-crosstenant.ps1:1609 char:1
+ connect-azureAD -Credential $credential
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : AuthenticationError: (:) [Connect-AzureAD], HttpRequestException
+ FullyQualifiedErrorId : Connect-AzureAD,Microsoft.Open.Azure.AD.CommonLibrary.ConnectAzureAD
connect-azureAD : {“error”:”interaction_required”,”error_description”:”AADSTS50076: Due to a configuration change made by your
administrator, or because you moved to a new location, you must use multi-factor authentication to access
‘00000002-0000-0000-c000-000000000000’.\r\nTrace ID: f895017b-daa6-49e7-9d93-744a6b583700\r\nCorrelation ID:
0c9a057c-e20e-4bb3-b9ae-2b6e96906691\r\nTimestamp: 2022-09-28 12:45:02Z”,”error_codes”:[50076],”timestamp”:”2022-09-28 12:45:02Z”,”tr
ace_id”:”f895017b-daa6-49e7-9d93-744a6b583700″,”correlation_id”:”0c9a057c-e20e-4bb3-b9ae-2b6e96906691″,”error_uri”:”https://login.mic
rosoftonline.com/error?code=50076″,”suberror”:”basic_action”}: Unknown error
At C:\Scripts\copy-intune-policy-crosstenant.ps1:1609 char:1
+ connect-azureAD -Credential $credential
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : AuthenticationError: (:) [Connect-AzureAD], AdalException
+ FullyQualifiedErrorId : Connect-AzureAD,Microsoft.Open.Azure.AD.CommonLibrary.ConnectAzureAD
connect-azureAD : One or more errors occurred.: AADSTS50076: Due to a configuration change made by your administrator, or because
you moved to a new location, you must use multi-factor authentication to access ‘00000002-0000-0000-c000-000000000000’.
Trace ID: f895017b-daa6-49e7-9d93-744a6b583700
Correlation ID: 0c9a057c-e20e-4bb3-b9ae-2b6e96906691
Timestamp: 2022-09-28 12:45:02Z
At C:\Scripts\copy-intune-policy-crosstenant.ps1:1609 char:1
+ connect-azureAD -Credential $credential
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Connect-AzureAD], AadAuthenticationFailedException
+ FullyQualifiedErrorId : Microsoft.Open.Azure.AD.CommonLibrary.AadAuthenticationFailedException,Microsoft.Open.Azure.AD.CommonL
ibrary.ConnectAzureAD
Connect-MSGraph : AADSTS50076: Due to a configuration change made by your administrator, or because you moved to a new location, you
must use multi-factor authentication to access ‘00000003-0000-0000-c000-000000000000’.
Trace ID: bb2abbd8-5988-4b60-b903-d1133b987000
Correlation ID: 7c20492c-499c-49c3-bff9-2b02de5174cf
Timestamp: 2022-09-28 12:45:03Z
At C:\Scripts\copy-intune-policy-crosstenant.ps1:1611 char:1
+ Connect-MSGraph -Credential $credential -PassThru
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Connect-MSGraph], AdalClaimChallengeException
+ FullyQualifiedErrorId : Microsoft.IdentityModel.Clients.ActiveDirectory.AdalClaimChallengeException,Microsoft.Intune.PowerShel
lGraphSDK.PowerShellCmdlets.Connect
I think i get this because i don’t get a MFA when i login with the script.
Charles
Hi Charles, that sounds like it might be a conditional access policy blocking movement. Do you get the error on source or destination tenant?
I`m trying to copy some policies but I always get this errors. Do you know what is going wrong here?
ERROR1:
It’s a policy
deviceManagement/deviceConfigurations
Exception setting “omaSettings”: “The property ‘omaSettings’ cannot be found on this object. Verify that the property exists and can be set.”
At line:1329 char:14
+ $policy.omaSettings = $policyconvert
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], SetValueInvocationException
+ FullyQualifiedErrorId : ExceptionWhenSetting
ERROR2:
Invoke-RestMethod : The remote server returned an error: (400) Bad Request.
At line:1842 char:27
+ … opypolicy = Invoke-RestMethod -Uri $policyuri -Headers $authToken -Me …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
Hi, what policy type is it you are trying to copy? It looks like I’ll need to tweak the script a bit to ignore omaSettings. Thanks
I get different errors for source and destination, for example:
“Connect-MSGraph : AADSTS50076: Due to a configuration change made by your administrator, or because you moved to a new
location, you must use multi-factor authentication to access ‘00000003-0000-0000-c000-000000000000’.”
or
“connect-azureAD : Response status code does not indicate success: 400 (BadRequest).”
The Connect-MSGraph is with the credentials from the Get-Credentials, so it’s not MFA right?
That looks more like a Conditional Access policy blocking things. It might be worth looking at the Azure AD sign-in logs to see what’s catching you. Feel free to use the contact form if you want me to take a look offline
Very nice scripts Andrew, thank you!
Unfortunatly it’s not working for most of my tenants because of MFA. Are you planing to integrate that?
Hi, it should work with MFA enabled as it uses modern authentication. Is it source or destination where it is failing (or both)? Does it give you any error messages?
Yes this looks great! Super work on it! Did a test.
Works with PowerShell 5, but if I try PS 7 (run via terminal), i get error below. PS 5
Checking for AzureAD module…
Authorization Access Token is null, please re-run authentication…
I dont see conditional access policies appear. From my demo/staging tenant. Mine are mostly report-only, but there is a couple switched on.
Anyway, looks great. Just spotted the Type column to sort. And can see Endpoint security policies in there also.
Dont know what you mean by proactive remediations? Like a health check comparison versus baseline security config?
I’ll update my PS and give it a test and see what’s going on with that.
For proactive remediations, it can now grab those (detection and remediation scripts included) and copy those between tenants as well
Thanks Andrew . Have others in the past but will give this a go.
Hopefully it all works ok. I’m always adding new features so if you think anything else would be useful, let me know.
Excellent tool. Just saved me hours of work. Thank you. As someone has suggested already, a copy of security groups which follow naming convention, but also is it possible to do the same for conditional access policies (report-only)? The areas it takes time to create, but probably follow best practice or a company standard.
Good idea, thank you. I’ll start testing that and see if I can get it added
Excellent. If you need any help testing let me know. Was also thinking a copy of endpoint security baselines and AV, firewall, EDR, ASR, etc. Basically anything that requires typing out. Happy to collaborate on this also, to lessen the load.
Thank you, shall do! It should already copy baselines and other security settings, they should display towards the bottom of the list.
Conditional access policies are next on the list, just trying to get the Authtoken to work in a different scope as CA and AAD Groups are at the user level and everything else so far has been device policy level.
I’ve just released version 3.0 which adds Conditional Access, Proactive Remediations and Azure AD Groups
After you run this command (from powershell) Install-Script -Name copy-intune-policy-crosstenant, then how do you actually run the script to bring up the GUI?
In PowerShell, once installed, just type copy-intune-policy-crosstenant.ps1 and it should launch. Once it’s logged you in, the GUI will appear
Hi
I managed to get it to run, after a few attempts, but now get a error (400) bad request
It ran initially and copied a number of polices, but would not copy some configuration polices over, and i still cannot get these same ones to copy across.
It does not seem to make a difference if I select 1 of these polices or multiple, i get the same error
the log below
Transcript started, output file is C:\Users\Keith\AppData\Local\Temp\intune-31082022.log
Microsoft Graph Already Installed
AZ Ad Preview Module Already Installed
Checking for AzureAD module…
35cfd4a4-77b5-44b2-b4d8-16736a8ac885
PS>TerminatingError(Invoke-RestMethod): “The remote server returned an error: (400) Bad Request.”
PS>TerminatingError(Invoke-RestMethod): “The remote server returned an error: (400) Bad Request.”
It’s a policy
deviceManagement/deviceConfigurations
The authtoken is null.
Checking for AzureAD module…
PS>TerminatingError(Invoke-RestMethod): “The remote server returned an error: (400) Bad Request.”
C:\Users\Keith\Documents\Untitled1.ps1 : System.Net.WebException: The remote server returned an error: (400) Bad
Request.
at Microsoft.PowerShell.Commands.WebRequestPSCmdlet.GetResponse(WebRequest request)
at Microsoft.PowerShell.Commands.WebRequestPSCmdlet.ProcessRecord()
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Untitled1.ps1
C:\Users\Keith\Documents\Untitled1.ps1 : System.Net.WebException: The remote server returned an error: (400) Bad Request.
at Microsoft.PowerShell.Commands.WebRequestPSCmdlet.GetResponse(WebRequest request)
at Microsoft.PowerShell.Commands.WebRequestPSCmdlet.ProcessRecord()
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Untitled1.ps1
**********************
Windows PowerShell transcript end
End time: 20220831144854
**********************
Hi Keith,
I’ve just deployed v2.1.3, can you see if that works any better?
What type of policy is it that is failing? I’ll try testing it from my side to see if I can replicate
Hi
I will test the new version in the morning.
The policy is a configuration profile, ncsc applocker
Hi
I tried v2.1.3 and same issue.
Could it be that the target tenant already has a policy with the same settings as the one i am trying to copy across?
Hi
Tried this today from a couple device, get same issues.
Script asks for inputs, one being email, after I enter that PowerShell want to save the script. When I save PowerShell closes.
If I reopen saved file and try again I get same thing. The GUI does not open and it doesn’t connect to tenant
Hi,
Any chance you can send me the transcript from %temp%\intune.log?
Is it the latest version 2 script you are running?
Hi,
After logon to destination tenant i got the following error:
addpolicy : System.Net.WebException: The remote server returned an error: (400) Invalid command..
At Microsoft.PowerShell.Commands.WebRequestPSCmdlet.GetResponse(WebRequest request)
At Microsoft.PowerShell.Commands.WebRequestPSCmdlet.ProcessRecord()
At $dir\PowerShell\Scripts\copy-intune-policy-crosstenant.ps1:1109 char:15
+ $copypolicy = addpolicy -resource $Resource -policyid $id
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,addpolicy
Using the AzureADPreview module instead of AzureAD.
Any idea?
Hi, is the preview module definitely running? I’ve seen it before where it still defaults to the AzureAD one and you have to unload the non-preview first
Hi Andrew,
I did try it on a clean machine after confirming it is unloaded on my one.
But got still the same error.
On the clean machine i first installed the AzureADPreview module.
What type of policy is it you are copying? Does the policy name have any special characters or anything in it?
It might be worth trying the single tenant version as well to see if the issue is with the script, or something on the destination tenant. Feel free to drop me a message directly if it’s easier
Hi,
Send you a e-mail with the logfile.
Version 2.2.1 now released which fixes the issue with Settings Catalog and the MS Graph module
Hi Andrew,
Love the script, been looking for something like this for quite a while.
I see this script does not support multiple policies to be migrated at the same time. Is this by design or not yet supported?
Also, I seem to be getting this error: is it anything to worry about?
Transcript started, output file is C:\Users\######\AppData\Local\Temp\intune-24082022.log
Clear-Variable : Cannot find a variable with the name ‘authResult’.
At C:\Users\#######\copy-intune-policy-crosstenant.ps1:965 char:1
+ Clear-Variable -Name authResult -Scope Global
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (authResult:String) [Clear-Variable], ItemNotFoundException
+ FullyQualifiedErrorId : VariableNotFound,Microsoft.PowerShell.Commands.ClearVariableCommand
Please specify your destination tenant email address: #########
That’s by design currently. For whole environments I would suggest the IntuneBackupandRestore module.
I will see if I can add a checkbox to give the option of selecting a few policies though.
I wouldn’t worry about the error, the graph tokens can be a bit fussy so I was extra brutal in killing them off, it just means it’s already ended the graph session for the source tenant
Hello Andrew, this is awesome! Are you planning please to create a similar script that will copy AAD groups / users and groups membership to a new tenant as well (to be able to recreate core AAD+Intune configuration in a new tenant)?
That’s a good idea, I’ll leave users themselves alone as they are often AAD synchronised, but will see if I can put something together to grab the groups and re-create including group memberships. Watch this space…
I’ve just released version 3.0 which adds Conditional Access, Proactive Remediations and Azure AD Groups
Awesome Andrew and thank you very much!