Microsoft Graph
5 TopicsExchange 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 and Microsoft.Graph.Authentication module before connecting to Exchange online clearing the token cache file from AppData\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/1816 seems 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?Solved6.6KViews0likes13CommentsCombine both : Get-MgBetaUser and Get-MgBetaReportAuthenticationMethodUserRegistrationDetail
Hi Guys I want to pull all user login details in Entra together ith MFA details for each user using the two modules to end up with an array for extracting a report like below. Kindly assist in joining data from the two modules, thank you. $mfaData = Get-MgBetaReportAuthenticationMethodUserRegistrationDetail -Identity $user | Select-Object UserDisplayName,UserPrincipalName, UserType,IsAdmin,DefaultMfaMethod,IsMfaRegistered,IsMfaCapable,IsPasswordlessCapable, MethodsRegistered $userData = @() foreach ($user in $entraIdUsers) { $entraIdUsers = Get-MgBetaUser -All -Property Id, DisplayDisplayNameName, UserPrincipalName, SignInActivity, CreatedDateTime, AccountEnabled $userData += [PSCustomObject]@{ "Id" = $user.Id "DisplayName" = $user.DisplayName "UPN" = $user.UserPrincipalName "CreatedDate" = $user.CreatedDateTime "AccountEnabled" = $user.AccountEnabled "LastSuccessfulSigninDate" = $user.SignInActivity.lastSuccessfulSignInDateTime "LastInteractiveSignIn" = $user.SignInActivity.LastSignInDateTime "LastNon_InteractiveSignIn" = $user.LastNonInteractiveSignInDateTime "UserType" = $mfaData.UserType "IsAdmin" = $mfaData.IsAdmin "IsMfaRegistered" = $mfaData.IsMfaRegistered "IsMfaCapable" = $mfaData.IsMfaCapable "IsPasswordlessCapable" = $mfaData.IsPasswordlessCapable "DefaultMfaMethod" = $mfaData.DefaultMfaMethod "UserPreferredMethodForSecondaryAuthentication" = $mfaData.UserPreferredMethodForSecondaryAuthentication "Methods registered" = $mfaData.MethodsRegistered -join ", " } }Solved790Views0likes1CommentUpdate Azure AD / Microsoft 365 users information - Office Phone numbers from a CSV file
Hello, I am trying to update the Office Phone numbers of my Microsoft 365 users using a list in a CSV file. Generally, the code works - it successfully updates all other attributes that are in the code (JobTitle, City, Office, etc.). Code: # Connect to Azure using the Az module Connect-AzAccount # Import the CSV file $csvPath = 'C:\Temp\AzureADUserAttributes.csv' $users = Import-Csv -Path $csvPath # Iterate through each user in the CSV and update their information foreach ($user in $users) { $userPrincipalName = $user.UserPrincipalName # Retrieve the user using Az module $existingUser = Get-AzADUser -UserPrincipalName $userPrincipalName # Check if the user exists if ($existingUser) { # Construct a hashtable of properties to update $userProperties = @{} # Update properties if they exist in the CSV if ($user.JobTitle) { $userProperties['JobTitle'] = $user.JobTitle } if ($user.Department) { $userProperties['Department'] = $user.Department } if ($user.CompanyName) { $userProperties['CompanyName'] = $user.CompanyName } if ($user.City) { $userProperties['City'] = $user.City } if ($user.Country) { $userProperties['Country'] = $user.Country } if ($user.PostalCode) { $userProperties['PostalCode'] = $user.PostalCode } if ($user.State) { $userProperties['State'] = $user.State } if ($user.StreetAddress) { $userProperties['StreetAddress'] = $user.StreetAddress } if ($user.Office) { $userProperties['Office'] = $user.Office } # Update user information only if there are properties to update if ($userProperties.Count -gt 0) { # Update user information using Az module Set-AzADUser -UserPrincipalName $userPrincipalName @userProperties Write-Host "User information updated for $userPrincipalName" } else { Write-Host "No properties to update for $userPrincipalName" } } else { Write-Host "User not found: $userPrincipalName" } } # Disconnect from Azure session (if needed) Disconnect-AzAccount However, when I add a new line after line 29 (if ($user.Office) { $userProperties['Office'] = $user.Office }) new line if ($user.TelephoneNumber) { $userProperties['TelephoneNumber'] = $user.TelephoneNumber } it throws an error: Update-AzADUser : A parameter cannot be found that matches parameter name 'TelephoneNumber'. At C:\Path\Update Bulk Azure AD Users information.ps1:36 char:64 + ... Set-AzADUser -UserPrincipalName $userPrincipalName @userProperties + ~~~~~~~~~~~~~~~ + CategoryInfo : InvalidArgument: (:) [Update-AzADUser], ParameterBindingException + FullyQualifiedErrorId : NamedParameterNotFound,Update-AzADUser In the CSV File, the column with the phone number is called the same as in the code i.e. "TelephoneNumber". I tried different names: OfficeNumber BusinessPhones PhoneNumber Phone etc., but with each there is the same error.Solved4.6KViews0likes3CommentsMethod not found 'Void Microsoft.Graph.TokenCredentialAuthProvider'
Hello, I try to run a runbook in Hybrid Worker to collect info from Azure Registered Apps. For that activity I connect to MS Graph with certificate and execute Get-MgApplication cmdlet. However, I see "Welcome to Microsoft Graph!" response and then: Get-MgApplication : Method not found: 'Void Microsoft.Graph.TokenCredentialAuthProvider..ctor(Azure.Core.TokenCredential, System.Collections.Generic.IEnumerable`1<System.String>)'. At line:24 char:1 + $SApps = Get-MgApplication -all + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [Get-MgApplication_List], MissingMethodException + FullyQualifiedErrorId : Microsoft.Graph.PowerShell.Cmdlets.GetMgApplication_List My current version module is 2.0.0-preview5, but I also tried other versions and got different results (but never successful). All cmdlets, including connecting via certificate, can be executed successfully locally and within Azure runbook. I run out of ideas. Any ideas?10KViews0likes6CommentsMicrosoft Graph and PowerShell - extracting the data into csv
Hey all, Hoping someone can point me in the right direction please? I'm messing about connecting up PowerShell (using PnP) to the Microsoft Graph API with a view of returning the data into a csv format. All I'm wanting to achieve is to retrieve the table header information and the results, is there a way to extrapolate that data out and output to a csv file? Many thanks, SteveSolved20KViews0likes2Comments