Exchange 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 FilesWindowsPowerShellModulesExchangeOnlineManagement3.5.1netFrameworkExchangeOnlineManagement.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.
I tired:
updateing both modules to the latest versionremoveing the Microsoft.Graph and Microsoft.Graph.Authentication module before connecting to Exchange onlineclearing the token cache file from AppDataLocal.IdentityServicemg.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.
Any idea why is this happening? What should i check?
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 commandConnect-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 FilesWindowsPowerShellModulesExchangeOnlineManagement3.5.1netFrameworkExchangeOnlineManagement.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. I tired:updateing both modules to the latest versionremoveing the Microsoft.Graph and Microsoft.Graph.Authentication module before connecting to Exchange onlineclearing the token cache file from AppDataLocal.IdentityServicemg.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. Any idea why is this happening? What should i check? Read More