M365 Powershell
1 TopicExchange online and MGGraph are interfering
I am creating a new script. The script is running unattended. The script doing a couple things, the important part here is: setting a new user a license and setting the new user mailbox Address book policy. The address book is an Exchange online task the license is Graph. I am getting an error. How to reproduce the error: 1. connect to MgGraph, I am using this command Connect-MgGraph -TenantId $tenantID -AppId $appID -CertificateThumbprint $CertificateThumbPrint -NoWelcome do some work, Disconnect-MgGraph 2. Connect to Exchange online, in the same script: Connect-ExchangeOnline -CertificateThumbPrint $CertificateThumbPrint -AppID $appID -Organization $tenantID -CommandName Get-EXOMailbox,Get-mailbox,Set-mailbox -SkipLoadingCmdletHelp -ShowBanner:$false The command verbose debug output is this: DEBUG: using System; using System.Net; using System.Management.Automation; using Microsoft.Win32.SafeHandles; using System.Security.Cryptography; using System.Runtime.InteropServices; using System.Runtime.ConstrainedExecution; using System.Runtime.Versioning; using System.Security; namespace Microsoft.PowerShell.Commands.PowerShellGet { public static class Telemetry { public static void TraceMessageArtifactsNotFound(string[] artifactsNotFound, string operationName) { Microsoft.PowerShell.Telemetry.Internal.TelemetryAPI.TraceMessage(operationName, new { ArtifactsNotFound = artifactsNotFound }); } public static void TraceMessageNonPSGalleryRegistration(string sourceLocationType, string sourceLocationHash, string installationPolicy, strin g packageManagementProvider, string publishLocationHash, string scriptSourceLocationHash, string scriptPublishLocationHash, string operationName) { Microsoft.PowerShell.Telemetry.Internal.TelemetryAPI.TraceMessage(operationName, new { SourceLocationType = sourceLocationType, SourceLoca tionHash = sourceLocationHash, InstallationPolicy = installationPolicy, PackageManagementProvider = packageManagementProvider, PublishLocationHash = p ublishLocationHash, ScriptSourceLocationHash = scriptSourceLocationHash, ScriptPublishLocationHash = scriptPublishLocationHash }); } } /// <summary> /// Used by Ping-Endpoint function to supply webproxy to HttpClient /// We cannot use System.Net.WebProxy because this is not available on CoreClr /// </summary> public class InternalWebProxy : IWebProxy { Uri _proxyUri; ICredentials _credentials; public InternalWebProxy(Uri uri, ICredentials credentials) { Credentials = credentials; _proxyUri = uri; } /// <summary> /// Credentials used by WebProxy /// </summary> public ICredentials Credentials { get { return _credentials; } set { _credentials = value; } } public Uri GetProxy(Uri destination) { return _proxyUri; } public bool IsBypassed(Uri host) { return false; } } [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)] public struct CERT_CHAIN_POLICY_PARA { public CERT_CHAIN_POLICY_PARA(int size) { cbSize = (uint) size; dwFlags = 0; pvExtraPolicyPara = IntPtr.Zero; } public uint cbSize; public uint dwFlags; public IntPtr pvExtraPolicyPara; } [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)] public struct CERT_CHAIN_POLICY_STATUS { public CERT_CHAIN_POLICY_STATUS(int size) { cbSize = (uint) size; dwError = 0; lChainIndex = IntPtr.Zero; lElementIndex = IntPtr.Zero; pvExtraPolicyStatus = IntPtr.Zero; } public uint cbSize; public uint dwError; public IntPtr lChainIndex; public IntPtr lElementIndex; public IntPtr pvExtraPolicyStatus; } // Internal SafeHandleZeroOrMinusOneIsInvalid class to remove the dependency on .Net Framework 4.6. public abstract class InternalSafeHandleZeroOrMinusOneIsInvalid : SafeHandle { protected InternalSafeHandleZeroOrMinusOneIsInvalid(bool ownsHandle) : base(IntPtr.Zero, ownsHandle) { } public override bool IsInvalid { get { return handle == IntPtr.Zero || handle == new IntPtr(-1); } } } // Internal SafeX509ChainHandle class to remove the dependency on .Net Framework 4.6. [SecurityCritical] public sealed class InternalSafeX509ChainHandle : InternalSafeHandleZeroOrMinusOneIsInvalid { private InternalSafeX509ChainHandle () : base(true) {} internal InternalSafeX509ChainHandle (IntPtr handle) : base (true) { SetHandle(handle); } internal static InternalSafeX509ChainHandle InvalidHandle { get { return new InternalSafeX509ChainHandle(IntPtr.Zero); } } [SecurityCritical] override protected bool ReleaseHandle() { CertFreeCertificateChain(handle); return true; } [DllImport("Crypt32.dll", SetLastError=true)] [SuppressUnmanagedCodeSecurity, ResourceExposure(ResourceScope.None), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] private static extern void CertFreeCertificateChain(IntPtr handle); } public class Win32Helpers { [DllImport("Crypt32.dll", CharSet=CharSet.Auto, SetLastError=true)] public extern static bool CertVerifyCertificateChainPolicy( [In] IntPtr pszPolicyOID, [In] SafeX509ChainHandle pChainContext, [In] ref CERT_CHAIN_POLICY_PARA pPolicyPara, [In,Out] ref CERT_CHAIN_POLICY_STATUS pPolicyStatus); [DllImport("Crypt32.dll", CharSet=CharSet.Auto, SetLastError=true)] public static extern SafeX509ChainHandle CertDuplicateCertificateChain( [In] IntPtr pChainContext); [DllImport("Crypt32.dll", CharSet=CharSet.Auto, SetLastError=true)] [ResourceExposure(ResourceScope.None)] public static extern SafeX509ChainHandle CertDuplicateCertificateChain( [In] SafeX509ChainHandle pChainContext); public static bool IsMicrosoftCertificate([In] SafeX509ChainHandle pChainContext) { //------------------------------------------------------------------------- // CERT_CHAIN_POLICY_MICROSOFT_ROOT // // Checks if the last element of the first simple chain contains a // Microsoft root public key. If it doesn't contain a Microsoft root // public key, dwError is set to CERT_E_UNTRUSTEDROOT. // // pPolicyPara is optional. However, // MICROSOFT_ROOT_CERT_CHAIN_POLICY_ENABLE_TEST_ROOT_FLAG can be set in // the dwFlags in pPolicyPara to also check for the Microsoft Test Roots. // // MICROSOFT_ROOT_CERT_CHAIN_POLICY_CHECK_APPLICATION_ROOT_FLAG can be set // in the dwFlags in pPolicyPara to check for the Microsoft root for // application signing instead of the Microsoft product root. This flag // explicitly checks for the application root only and cannot be combined // with the test root flag. // // MICROSOFT_ROOT_CERT_CHAIN_POLICY_DISABLE_FLIGHT_ROOT_FLAG can be set // in the dwFlags in pPolicyPara to always disable the Flight root. // // pvExtraPolicyPara and pvExtraPolicyStatus aren't used and must be set // to NULL. //-------------------------------------------------------------------------- const uint MICROSOFT_ROOT_CERT_CHAIN_POLICY_ENABLE_TEST_ROOT_FLAG = 0x00010000; const uint MICROSOFT_ROOT_CERT_CHAIN_POLICY_CHECK_APPLICATION_ROOT_FLAG = 0x00020000; //const uint MICROSOFT_ROOT_CERT_CHAIN_POLICY_DISABLE_FLIGHT_ROOT_FLAG = 0x00040000; CERT_CHAIN_POLICY_PARA PolicyPara = new CERT_CHAIN_POLICY_PARA(Marshal.SizeOf(typeof(CERT_CHAIN_POLICY_PARA))); CERT_CHAIN_POLICY_STATUS PolicyStatus = new CERT_CHAIN_POLICY_STATUS(Marshal.SizeOf(typeof(CERT_CHAIN_POLICY_STATUS))); int CERT_CHAIN_POLICY_MICROSOFT_ROOT = 7; PolicyPara.dwFlags = (uint) MICROSOFT_ROOT_CERT_CHAIN_POLICY_ENABLE_TEST_ROOT_FLAG; bool isMicrosoftRoot = false; if(CertVerifyCertificateChainPolicy(new IntPtr(CERT_CHAIN_POLICY_MICROSOFT_ROOT), pChainContext, ref PolicyPara, ref PolicyStatus)) { isMicrosoftRoot = (PolicyStatus.dwError == 0); } // Also check for the Microsoft root for application signing if the Microsoft product root verification is unsuccessful. if(!isMicrosoftRoot) { // Some Microsoft modules can be signed with Microsoft Application Root instead of Microsoft Product Root, // So we need to use the MICROSOFT_ROOT_CERT_CHAIN_POLICY_CHECK_APPLICATION_ROOT_FLAG for the certificate verification. // MICROSOFT_ROOT_CERT_CHAIN_POLICY_CHECK_APPLICATION_ROOT_FLAG can not be used // with MICROSOFT_ROOT_CERT_CHAIN_POLICY_ENABLE_TEST_ROOT_FLAG, // so additional CertVerifyCertificateChainPolicy call is required to verify the given certificate is in Microsoft Application Root. // CERT_CHAIN_POLICY_PARA PolicyPara2 = new CERT_CHAIN_POLICY_PARA(Marshal.SizeOf(typeof(CERT_CHAIN_POLICY_PARA))); CERT_CHAIN_POLICY_STATUS PolicyStatus2 = new CERT_CHAIN_POLICY_STATUS(Marshal.SizeOf(typeof(CERT_CHAIN_POLICY_STATUS))); PolicyPara2.dwFlags = (uint) MICROSOFT_ROOT_CERT_CHAIN_POLICY_CHECK_APPLICATION_ROOT_FLAG; if(CertVerifyCertificateChainPolicy(new IntPtr(CERT_CHAIN_POLICY_MICROSOFT_ROOT), pChainContext, ref PolicyPara2, ref PolicyStatus2)) { isMicrosoftRoot = (PolicyStatus2.dwError == 0); } } return isMicrosoftRoot; } } } IDX12729: Unable to decode the header '[PII of type 'System.String' is hidden. For more details, see https://aka.ms/IdentityModel/PII.]' as Base64Url encoded string. At C:\Program Files\WindowsPowerShell\Modules\ExchangeOnlineManagement\3.5.1\netFramework\ExchangeOnlineManagement.psm1:762 char:21 + throw $_.Exception.InnerException; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : OperationStopped: (:) [], ArgumentException + FullyQualifiedErrorId : IDX12729: Unable to decode the header '[PII of type 'System.String' is hidden. For more details, see https://aka.ms/Id entityModel/PII.]' as Base64Url encoded string. Exception details: $exception.Exception.Message # empty $exception.Exception.ParamName $exception.Exception.TargetSite # empty $exception.Exception.Data $exception.Exception.InnerException #empty $exception.Exception.HelpLink $exception.Exception.Source $exception.Exception.HResult $exception.Exception.StackTrace IDX12729: Unable to decode the header '[PII of type 'System.String' is hidden. For more details, see https://aka.ms/IdentityModel/PII.]' as Base64Url encoded string. Name : Decode DeclaringType : System.IdentityModel.Tokens.Jwt.JwtSecurityToken ReflectedType : System.IdentityModel.Tokens.Jwt.JwtSecurityToken MemberType : Method MetadataToken : 100663422 Module : System.IdentityModel.Tokens.Jwt.dll IsSecurityCritical : True IsSecuritySafeCritical : False IsSecurityTransparent : False MethodHandle : System.RuntimeMethodHandle Attributes : PrivateScope, Assembly, HideBySig CallingConvention : Standard, HasThis ReturnType : System.Void ReturnTypeCustomAttributes : Void ReturnParameter : Void IsGenericMethod : False IsGenericMethodDefinition : False ContainsGenericParameters : False MethodImplementationFlags : Managed IsPublic : False IsPrivate : False IsFamily : False IsAssembly : True IsFamilyAndAssembly : False IsFamilyOrAssembly : False IsStatic : False IsFinal : False IsVirtual : False IsHideBySig : True IsAbstract : False IsSpecialName : False IsConstructor : False CustomAttributes : {} A metódus nem található: „Void System.Text.Json.Utf8JsonReader..ctor(System.ReadOnlySpan`1<Byte>, System.Text.Json.JsonReaderOptions)”. System.IdentityModel.Tokens.Jwt -2147024809 a következő helyen: System.IdentityModel.Tokens.Jwt.JwtSecurityToken.Decode(String[] tokenParts, String rawData) a következő helyen: Microsoft.Exchange.Management.AdminApiProvider.Authentication.JwtSecurityTokenUtils.GetTenantId(String accessToken) a következő helyen: Microsoft.Exchange.Management.AdminApiProvider.Authentication.TokenProviderUtils.GetTokenInformation(AuthenticationResult token AcquisitionResult, TokenProviderContext context) a következő helyen: Microsoft.Exchange.Management.AdminApiProvider.Authentication.MSALTokenProvider.<GetAccessTokenAsync>d__34.MoveNext() I tired: updateing both modules to the latest version removeing the Microsoft.Graph andMicrosoft.Graph.Authentication module before connecting to Exchange online clearing the token cache file fromAppData\Local\.IdentityService\mg.msal.cache I would like to avoid running two separate script or script isolation like new processes or jobs. Because i need to pass many variables between the two script, input and output. The app I am using and the cert is okay. If i am running separately it is working, so I can connect Exchange online with it. This github issue:https://github.com/microsoftgraph/msgraph-sdk-powershell/issues/1816seems to have similar issue, but this was in 2023. There is a workaround, but I am unable to understand. Basically i should connect differently to Graph? or Exchange online? if so how? can anyone recommend a non interactive option? Any idea why is this happening? What should i check?Solved3.1KViews0likes12Comments