Code Monkey home page Code Monkey logo

mscloudloginassistant's Introduction

MSCloudLoginAssistant

A module for checking the current status of (and as required, prompting for login to) connections to various Microsoft Cloud platforms like Teams, Azure, and SharePoint Online.

Build status codecov

mscloudloginassistant's People

Contributors

andikrueger avatar bjoernf73 avatar brianlala avatar desmay avatar erbabtis avatar jorisbaiutti avatar manualbashing avatar markdomansky avatar microsoft-github-policy-service[bot] avatar microsoftopensource avatar msftgits avatar nikcharlebois avatar nikcharleboispfe avatar poiriersimon avatar raandree avatar swampen avatar william-francillette avatar ykuijs avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mscloudloginassistant's Issues

New connection to MSCommerce

The current implementation of the MSCommerce module does not allow to pass credentials into Connect-MSCommerce cmdLet. The module is used to change the self service licensing options within PowerPlatform.

The implementation could be very similar to Get-PowerPlatformTokenInfo:

$ClientId = "3d5cffa9-04da-4657-8cab-c7f074657cad"
$Resource = "aeb86249-8ea3-49e2-900b-54cc8e308f85" # Licensemanager API
$O365Credentials

Import-Module 'Microsoft.PowerApps.Administration.PowerShell' -Force
$authContext = New-Object Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext("https://login.windows.net/common");
$credential = [Microsoft.IdentityModel.Clients.ActiveDirectory.UserCredential]::new($O365Credentials.Username, $O365Credentials.Password)
$token = $authContext.AcquireToken($Resource, $ClientId, $O365Credentials) 

Error stem.Exception: AADSTS90010: The grant type is not supported over the /common or /consumers endpoints

I have this error when i run Test-MSCloudLogin -Platform SecurityComplianceCenter.

This results also in an error in M365DSC when applying sensitivity labels. Because of this error the credential modal opens and modals are not supported in dsc background tasks.

Full Stack trace:
Error Acquiring Token:
System.Exception: AADSTS90010: The grant type is not supported over the /common or /consumers endpoints. Please use the /organizations or tenant-specific endpoint you used common.
Mitigation: as explained in the message from Azure AD, the authority you use in the application needs to be tenanted or otherwise organizations. change the "Tenant": property in the appsettings.json to be a GUID (tenant Id), or domain name (contoso.com) if such a domain is registered with your tenantor "organizations", if you want this application to sign-in users in any Work and School accounts.
InnerException : AADSTS9001023: The grant type is not supported over the /common or /consumers endpoints. Please use the /organizations or tenant-specific endpoint.
Trace ID: e5e4bd53-1262-4031-89fc-4ea82cc14200
Correlation ID: eb0bb5eb-f41c-42e7-ac05-bd3c5017780b
Timestamp: 2021-02-22 13:58:36Z ---> Microsoft.Identity.Client.MsalServiceException: AADSTS9001023: The grant type is not supported over the /common or /consumers endpoints. Please use the /organizations or tenant-specific endpoint.
Trace ID: e5e4bd53-1262-4031-89fc-4ea82cc14200
Correlation ID: eb0bb5eb-f41c-42e7-ac05-bd3c5017780b
Timestamp: 2021-02-22 13:58:36Z
at Microsoft.Identity.Client.OAuth2.OAuth2Client.ThrowServerException(HttpResponse response, RequestContext requestContext)
at Microsoft.Identity.Client.OAuth2.OAuth2Client.CreateResponse[T](HttpResponse response, RequestContext requestContext)
at Microsoft.Identity.Client.OAuth2.OAuth2Client.d__11`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Identity.Client.OAuth2.OAuth2Client.d__10.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Identity.Client.OAuth2.TokenClient.d__8.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.Identity.Client.OAuth2.TokenClient.d__8.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Identity.Client.OAuth2.TokenClient.d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Identity.Client.Internal.Requests.RequestBase.d__20.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Identity.Client.Internal.Requests.UsernamePasswordRequest.d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Identity.Client.Internal.Requests.RequestBase.d__13.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Identity.Client.ApiConfig.Executors.PublicClientExecutor.d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Exchange.Management.AdminApiProvider.Authentication.MSALTokenProvider.d__20.MoveNext()
--- End of inner exception stack trace ---
at Microsoft.Exchange.Management.AdminApiProvider.Authentication.MSALTokenProvider.d__20.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Exchange.Management.AdminApiProvider.Authentication.MSALTokenProvider.d__22.MoveNext()
Error Acquiring Token:
User canceled authentication.

Exporting SPOUserProfileProperties - Export-M365DSCConfiguration

Used the following cmdlet to export all the following components using Certificate and Thumbprint:

Export-M365DSCConfiguration -Components @("ODSettings", "SPOAccessControlSettings", "SPOApp", "SPOBrowserIdleSignout", "SPOHomeSite", "SPOHubSite", "SPOOrgAssetsLibrary", "SPOPropertyBag", "SPOSearchManagedProperty", "SPOSearchResultSource", "SPOSharingSettings", "SPOSite", "SPOSiteAuditSettings", "SPOSiteDesign", "SPOSiteDesignRights", "SPOSiteGroup", "SPOSiteScript", "SPOStorageEntity", "SPOTenantCdnEnabled", "SPOTenantCdnPolicy", "SPOTenantSettings", "SPOTheme", "SPOUserProfileProperty") -ApplicationId $ApplicationId -CertificateThumbprint $CertificateThumbprint -TenantId $TenantId -Path "c:\M365DSC\demo3" -FileName "M365xBBBBBBB.ps1"

Experienced the following exception mentioned in the Error Log file:

{InvalidData}
System.Management.Automation.ParameterBindingValidationException: Cannot bind argument to parameter 'Properties' because it is null.
at System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext, Exception exception)
at System.Management.Automation.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
"Error during Export:"
at Export-TargetResource, C:\Program Files\WindowsPowerShell\Modules\Microsoft365DSC\1.23.510.1\DSCResources\MSFT_SPOUserProfileProperty\MSFT_SPOUserProfileProperty.psm1: line 329
at Start-M365DSCConfigurationExtract, C:\Program Files\WindowsPowerShell\Modules\Microsoft365DSC\1.23.510.1\modules\M365DSCReverse.psm1: line 619
at Export-M365DSCConfiguration, C:\Program Files\WindowsPowerShell\Modules\Microsoft365DSC\1.23.510.1\modules\M365DSCUtil.psm1: line 1288
at , : line 1
TenantId: M365xBBBBBBB.onmicrosoft.com

Anyone experienced this before? if so, any suggestions.

Add a ClientID & RedirectURI parameter

For PnP, for example, it is possible to pass in the ClientID and ReturnURI so that the Connect-PnPOnline can use an Azure AD App with delegated privileges to authenticate. This would help get around the MFA GUI Prompt restriction (UserInteractive Mode) in the Forward Office365DSC path.

Can’t create an Exchange Connection for certain MFA users

For some reasons, this line of code never returns any session back for certain users which causes the message to let users know they exceeded the max # of connections and that they have to wait for 60 seconds indefinitely.

                   $Global:ExchangeOnlineSession = New-PSSession -Name 'ExchangeOnline' -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $O365Credential -Authentication Basic -AllowRedirection -ErrorAction SilentlyContinue

Depth Overflow

When trying to login using my own ApplicationID, TenantID and cert thumbprint I get this error:

Connect-M365Tenant : The script failed due to call depth overflow.
At D:\Scripts\bin\Modules\MSCloudLoginAssistant\1.0.94\MSCloudLoginAssistant.psm1:866 char:9

  •     Connect-M365Tenant -Workload MicrosoftGraph -ApplicationId $A ...
    
  •     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : InvalidOperation: (0:Int32) [Connect-M365Tenant], RuntimeException
    • FullyQualifiedErrorId : CallDepthOverflow,Connect-M365Tenant

Am I missing something in my Azure APP config?

Cannot connect to Graph API with Managed Identity

When I try to connect to Graph API with Managed Identity I get a timeout error, that there is no response from the IP-Address 69.254.169.254.
Digging further, I found a If/Else Condition in the MicrosoftGraph.psm1 file in line 47:
There is a check if the $env:AZUREPS_HOST_ENVIRONMENT variable is equal to "AzureAutomation/".
When I check the variable in my Runbook, the variable is set to "AzureAutomation", without the slash at the end.
When I change the variable to "AzureAutomation/", everything is working fine.

The Catch block in Connect-MSCloudLoginPnP isn't handling all exceptions

I was testing an issue with Microsoft365Dsc and noticed that Test-MSCloudLogin wasn't connecting to the correct SharePoint site. After some troubleshooting, I noticed that the Connect-MSCloudLoginPnP function isn't handling all exceptions. The login has a few if/elseif statements, but if the thrown exception isn't any of the specified exceptions, the code just ignores it.

The issue I had was that my account didn't have the proper permissions on the site collection, which caused the function not to connect to it but didn't throw an error or display a message. Debugging showed that the following exception was thrown, but the catch block didn't do anything with it:

Connect-PnPOnline : The remote server returned an error: (403) Forbidden.
At C:\Program Files\WindowsPowerShell\Modules\MSCloudLoginAssistant\1.0.48\Workloads\PnP.psm1:120 char:17
+                 Connect-PnPOnline -Url $Global:SPOConnectionUrl `
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Connect-PnPOnline], WebException
    + FullyQualifiedErrorId : System.Net.WebException,PnP.PowerShell.Commands.Base.ConnectOnline

Would it be an idea to add an Else statement that handles all exceptions that aren't handled earlier in the code?

Involved code:

catch
{
if ($_.Exception -like '*AADSTS50076*')
{
try
{
if ($Global:CloudEnvironment -eq 'GCCHigh')
{
$Global:SPOConnectionUrl = $Global:SPOConnectionUrl.Replace('.com', '.us')
Connect-PnPOnline -Url $Global:SPOConnectionUrl -UseWebLogin
$Global:IsMFAAuth = $true
$Global:MSCloudLoginAzurePnPConnected = $true
}
else
{
Connect-PnPOnline -Url $Global:SPOConnectionUrl -UseWebLogin
$Global:IsMFAAuth = $true
$Global:MSCloudLoginAzurePnPConnected = $true
}
}
catch
{
$Global:MSCloudLoginAzurePnPConnected = $false
throw $_
}
}
elseif ($_.Exception -like '*The sign-in name or password does not match one in the Microsoft account system*')
{
# This error means that the account was trying to connect using MFA.
try
{
if ($null -eq $Global:SPOAdminUrl)
{
$Global:SPOAdminUrl = Get-SPOAdminUrl -CloudCredential $Global:o365Credential
}
Write-Verbose "Trying to acquire AccessToken"
$AuthHeader = Get-AuthHeader -UserPrincipalName $Global:o365Credential.UserName `
-ResourceURI $Global:SPOAdminUrl -clientID $clientID -RedirectURI $RedirectURI
$AccessToken = $AuthHeader.split(" ")[1]
Write-Verbose "Access Token = $AccessToken"
if ($null -ne $AccessToken)
{
Connect-PnPOnline -Url $Global:SPOConnectionUrl -AccessToken $AccessToken
}
else
{
Connect-PnPOnline -Url $Global:SPOConnectionUrl -UseWebLogin
}
$Global:IsMFAAuth = $true
$Global:MSCloudLoginAzurePnPConnected = $true
}
catch
{
Write-Verbose "Error acquiring AccessToken: $_.Exception"
try
{
Connect-PnPOnline -Url $Global:SPOConnectionUrl -UseWebLogin
$Global:IsMFAAuth = $true
$Global:MSCloudLoginAzurePnPConnected = $true
}
catch
{
$Global:MSCloudLoginAzurePnPConnected = $false
throw $_
}
}
}
elseif ($_.Exception -like "*AADSTS65001: The user or administrator has not consented to use the application with ID*")
{
Write-Error "The PnP.PowerShell Azure AD Application has not been granted access for this tenant. Please run 'Register-PnPManagementShellAccess' to grant access and try again after."
}
}

PnP: `if (-not $Url)` should be `if ($Url)`

Note: this issue will be resolved in a PR coming shortly.

Problem

In PnP.psm1, for ServicePrincipalWithThumbprint the complete opposite of ServicePrincipalWithPath is used in the if-statement. The two should be identical. See my comments starting with # ====> ....

if ($Global:MSCloudLoginConnectionProfile.PnP.AuthenticationType -eq 'ServicePrincipalWithThumbprint')
        {
            # ====> Here, for Certificate Thumbprint, if (-not $url) is used
            if (-not $Url)
            {
                Write-Information -Message 'Connecting with Service Principal - Thumbprint'
                Write-Information -Message "URL: $Url"
                Write-Information -Message "ConnectionUrl: $($Global:MSCloudLoginConnectionProfile.PnP.ConnectionUrl)"
                Connect-PnPOnline -Url $Global:MSCloudLoginConnectionProfile.PnP.ConnectionUrl `
                    -ClientId $Global:MSCloudLoginConnectionProfile.PnP.ApplicationId `
                    -Tenant $Global:MSCloudLoginConnectionProfile.PnP.TenantId `
                    -Thumbprint $Global:MSCloudLoginConnectionProfile.PnP.CertificateThumbprint `
                    -AzureEnvironment $Global:MSCloudLoginConnectionProfile.PnP.PnPAzureEnvironment | Out-Null
            }
            elseif ($Global:MSCloudLoginConnectionProfile.PnP.AdminUrl)
            {
                Write-Information -Message 'Connecting with Service Principal - Thumbprint'
                Write-Information -Message "URL: $Url"
                Write-Information -Message "AdminUrl: $($Global:MSCloudLoginConnectionProfile.PnP.AdminUrl)"
                Connect-PnPOnline -Url $Global:MSCloudLoginConnectionProfile.PnP.AdminUrl `
                    -ClientId $Global:MSCloudLoginConnectionProfile.PnP.ApplicationId `
                    -Tenant $Global:MSCloudLoginConnectionProfile.PnP.TenantId `
                    -Thumbprint $Global:MSCloudLoginConnectionProfile.PnP.CertificateThumbprint `
                    -AzureEnvironment $Global:MSCloudLoginConnectionProfile.PnP.PnPAzureEnvironment | Out-Null
            }

            $Global:MSCloudLoginConnectionProfile.PnP.ConnectedDateTime = [System.DateTime]::Now.ToString()
            $Global:MSCloudLoginConnectionProfile.PnP.MultiFactorAuthentication = $false
            $Global:MSCloudLoginConnectionProfile.PnP.Connected = $true
        }
        elseif ($Global:MSCloudLoginConnectionProfile.PnP.AuthenticationType -eq 'ServicePrincipalWithPath')
        {
            # ====> Here, for Certificate Path, if ($url) is used for exactly the same scenario
            if ($Url)
            {
                Write-Information -Message 'Connecting with Service Principal - Path'
                Write-Information -Message "URL: $Url"
                Write-Information -Message "ConnectionUrl: $($Global:MSCloudLoginConnectionProfile.PnP.ConnectionUrl)"
                Connect-PnPOnline -Url $Global:MSCloudLoginConnectionProfile.PnP.ConnectionUrl `
                    -ClientId $Global:MSCloudLoginConnectionProfile.PnP.ApplicationId `
                    -Tenant $Global:MSCloudLoginConnectionProfile.PnP.TenantId `
                    -CertificatePassword $Global:MSCloudLoginConnectionProfile.PnP.CertificatePassword `
                    -CertificatePath $Global:MSCloudLoginConnectionProfile.PnP.CertificatePath `
                    -AzureEnvironment $Global:MSCloudLoginConnectionProfile.PnP.PnPAzureEnvironment
            }
            else
            {
                Write-Information -Message 'Connecting with Service Principal - Path'
                Write-Information -Message "URL: $Url"
                Write-Information -Message "AdminUrl: $($Global:MSCloudLoginConnectionProfile.PnP.AdminUrl)"
                Connect-PnPOnline -Url $Global:MSCloudLoginConnectionProfile.PnP.AdminUrl `
                    -ClientId $Global:MSCloudLoginConnectionProfile.PnP.ApplicationId `
                    -Tenant $Global:MSCloudLoginConnectionProfile.PnP.TenantId `
                    -CertificatePassword $Global:MSCloudLoginConnectionProfile.PnP.CertificatePassword `
                    -CertificatePath $Global:MSCloudLoginConnectionProfile.PnP.CertificatePath `
                    -AzureEnvironment $Global:MSCloudLoginConnectionProfile.PnP.PnPAzureEnvironment
            }

            $Global:MSCloudLoginConnectionProfile.PnP.ConnectedDateTime = [System.DateTime]::Now.ToString()
            $Global:MSCloudLoginConnectionProfile.PnP.MultiFactorAuthentication = $false
            $Global:MSCloudLoginConnectionProfile.PnP.Connected = $true
        }

Suggestion

For ServicePrincipalWithThumbprint, change from

if (-not $Url)
{..}

to

if ($Url)
{..}

Login not working on Azure automation account with managed identity

Managed Identity Login for VMs with msi works via

Invoke-RestMethod -Uri "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2F$($resourceEndpoint)%2F" -Headers @{Metadata = 'true' }

This throws an "unable to connect to the remote server" error on automation accounts.

Reason is the different URL for the the Identity endpoint as described here:

https://learn.microsoft.com/en-us/azure/automation/enable-managed-identity-for-automation

This code example shows, how the endpoint has to be used on automation accounts ($env:IDENTITY_ENDPOINT is "http://127.0.0.1:20072/oauth2/token" in my account)

$resource= "?resource=https://management.azure.com/"
$url = $env:IDENTITY_ENDPOINT + $resource
$Headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$Headers.Add("X-IDENTITY-HEADER", $env:IDENTITY_HEADER)
$Headers.Add("Metadata", "True")
$accessToken = Invoke-RestMethod -Uri $url -Method 'GET' -Headers $Headers
Write-Output $accessToken.access_token

Have you considered script: scoped variables?

My experience with script: scope in modules is that it keeps the variable in memory with the life of the module, just like a global: but without exposing the credential to every script. This would also ensure that variables like MSCloudLoginTeamsConnected aren't unintentionally or maliciously modified.

If there's intent/benefit behind using global: I'd like to learn something new.

Teams and MFA - Cannot find an overload for "AcquireTokenAsync" and the argument count: "5".

There is an issue with Teams and MFA where we are not able to get the MFA prompt to appear when running Export-O365Configuration. It works fine when running it with Test-MSCloudLoginAssistant directly. The popup never appears. It appears that the ADAL object created has an extra property on its AuthContext when executed through the Export-O365Configuration path. The OwnerWindow property isn't on the object when using the direct Test-MSCloudLogin route. We need to determine what the difference is here.

$Global:ADALServicePoint.authContext
Authority : https://login.windows.net/e7a80bcf-696e-40ca-8775-a7f85fbb3ebc/oauth2/authorize/
ValidateAuthority : False
TokenCache : Microsoft.IdentityModel.Clients.ActiveDirectory.TokenCache
CorrelationId : 00000000-0000-0000-0000-000000000000
OwnerWindow :

Teams workload doesn't properly reuse existing connection

Workload-specific function Connect-MSCloudLoginTeams mistakenly sets $MSCloudLoginConnectionProfile.ExchangeOnline.Connected to $true if an active PSSession referencing Teams exists. It should set $MSCloudLoginConnectionProfile.Teams.Connected = $true instead. I have created a PR for the resolution

[Workload Tasks] Certificates are only checked in CurrentUser store

The function Connect-MSCloudLoginTasksWithCertificateThumbprint only checks the CurrentUser store for the certificate with the given thumbprint, but does not check the store of the local machine.

This is problematic for us, or makes things more complicated, when used with Microsoft365DSC and the O365OrganizationSettings resource as this requires the certificate to be installed in the certificate store of the LCM user / LocalSystem user.

It would simplify things for us, if this function would use the local machine store, like the Microsoft Graph workload does, or if it at least would try both stores, if CurrentUser needs to be kept around for backwards compatibility.

Token lifetime handling in MSGraph and ApplicationSecret + Managed Identity

MS Graph with App Secret

Connections to Microsoft Graph with ApplicationSecret time out. The standard token lifetime for token issued oAuth is 60 minutes.

Right now MSCloudLoginAssistant does not check when the connection got established. This can cause issues with long running jobs that use an application secret for the login.

Potential issue with Managed Identity tokens

There might be an issue for managed identity too. At the moment, there is no logic implemented, that would check if tokens are valid. Most modules handle the token refresh on their own. This would only apply to modules that require a token to be passed into the connect method of a workload.

`Connect-ExchangeOnline` does not give write access due to wrong organization name

I want to control EXO settings with Microsoft365DSC. Reading data from EXO works but writing does not.

When passing the organization's short name to Connect-ExchangeOnline, not even creating a DL is possible, when using the FQDN things work. Unfortunately, the function Get-MSCloudLoginOrganizationName returns the short name. Why are we not returning the FQDN instead?

Connect-ExchangeOnline -ManagedIdentity -ShowBanner:$false -Organization MngEnvMCAP576786

New-DistributionGroup -Name t1

Disconnect-ExchangeOnline -Confirm:$false

Connect-ExchangeOnline -ManagedIdentity -ShowBanner:$false -Organization MngEnvMCAP576786.onmicrosoft.com

New-DistributionGroup -Name t1

Disconnect-ExchangeOnline -Confirm:$false

The first attempt returns an error, the second works as expected:

Write-ErrorMessage : |Microsoft.Exchange.Data.Directory.ADTransientException|Object 'CN=SystemMailbox{bb558c35-97f1-4cb9-8ff7-d53741dc928c},OU=MngEnvMCAP576786.onmicrosoft.com,OU=Microsoft Exchange Hosted 
Organizations,DC=NAMPR05A009,DC=PROD,DC=OUTLOOK,DC=COM' does not belong to partition 'GBRP265.PROD.OUTLOOK.COM' that current AD session is bound to.
At C:\Users\Install\AppData\Local\Temp\2\tmpEXO_slfy54m0.dej\tmpEXO_slfy54m0.dej.psm1:1191 char:13
+             Write-ErrorMessage $ErrorObject
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [New-DistributionGroup], ADTransientException
    + FullyQualifiedErrorId : [Server=LO6P265MB7049,RequestId=380184f3-bbd4-0239-f8c3-479397ca0f3a,TimeStamp=Mon, 01 Apr 2024 21:32:49 GMT],Write-ErrorMessage
 

Name DisplayName GroupType PrimarySmtpAddress                 
---- ----------- --------- ------------------                 
t1   t1          Universal [email protected]

Am I doing anything wrong?

Add support for deviceauthentication flow

we want to have an option for authentication with deviceauthentication..

connect-microsoftteams -UseDeviceAuthentication
connect-mggraph -UseDeviceAuthentication
connect-exchangeonline -Device

Usecase:
Using this in combination with Microsoft365DSC
--> Export-M365DSCConfiguration -UseDeviceAuthentication

Add support for VM managed identity

Consider leveraging VM managed identities as auth components, looks like 3 changes:

  1. ConnectionProfile - add Identity to AuthenticatioType list
  2. MicrosoftGraph - add Identity to profile
  3. MicrosoftGraph - add token-retrieval/connection to elseif section:
    Login-AzAccount -Identity $accessToken = (Get-AzAccessToken -ResourceTypeName MSGraph).Token Connect-MgGraph -AccessToken $accessToken $Global:MSCloudLoginConnectionProfile.MicrosoftGraph.ConnectedDateTime = [System.DateTime]::Now.ToString() $Global:MSCloudLoginConnectionProfile.MicrosoftGraph.MultiFactorAuthentication = $true $Global:MSCloudLoginConnectionProfile.MicrosoftGraph.Connected = $true $Global:MSCloudLoginConnectionProfile.MicrosoftGraph.TenantId = (Get-MGContext).TenantId

FWIW I have this operational with the MSFT_AAD* resources (attendant changes in M365DSCReverse, M365DSCUtil and AAD resources)

Improve Logging by removing '$VerbosePreference = 'SilentlyContinue'' Connect-M365Tenant

Is there a chance $VerbosePreference = 'SilentlyContinue' can be removed in Connect-M365Tenant


as it would make debugging connections in other workloads such as Microsoft365DSC much easier?

It kind of contradicts the fact that all output in the script is being produced by write-verbose.

Invoke-WebRequest isn't using -UseBasicParsing in MSCloudLoginAssistant.psm1

On line 602 in MSCloudLoginAssistant.psm1, the UseBasicParsing parameter isn't specified for the Invoke-WebRequest cmdlet. In Microsoft365Dsc, this is causing the following exception to be thrown:
"The response content cannot be parsed because the Internet Explorer module is not available, or the configuration is displayed the first time you start Internet explorer. Apply -usebasicparsing and try again."

On two other places in the file, UseBasicParsing is specified. Is there a specific reason it is not specified on this line?

$response = Invoke-WebRequest -Uri "https://login.microsoftonline.com/$tenantName/v2.0/.well-known/openid-configuration" -Method Get

PnP: Fail to connect to a SharePoint AdminUrl (`Connect-PnPOnline`) that has a redirector where the default AdminUrl used to be

Note: this issue will be resolved in a PR coming shortly.

Problem

Sharepoint Online-customers may have created a tenant with a specific name once in time, only to realize at a later stage that they had to rename their sharepoint domain, because the tenant name was not really what they wanted in their Sharepoint Online domain name, ref https://learn.microsoft.com/en-us/sharepoint/change-your-sharepoint-domain-name

MSCloudLoginAssisant is unable to detect when the Url it connects to is a redirector. When it does, operations (in Microsoft365Dsc) fail whenever Get-PnPTenant is ran. That function is ran for every resource that uses Connect-PnPOnline.

Suggestion

It should be able to

  1. detect when Url it connects to is a redirector,
  2. resolve the new Url/AdminUrl, and
  3. reconnect to that Url instead.

Usage Questions and Feedback

  1. It says it the module code notes that "MSCloudLoginAssistant.psm1" is for connecting to SharePoint Online and SharePoint PnP. However not seeing anything SPO specific, just PnP as platform/workload. Can you clarify on this?

  2. Why are there two cmdlets for connecting? Is the proper usage of this to always just use Test-MSCloudLogin?

  3. What is the reasoning being using Test-MSCloudLogin to pass parameters off to Connect-M365Tenant?

  4. Could you provide more detailed examples? I haven't been able to establish a connection with the PnP, even though the service account I am using has proper access rights. I've tried using the TenantId and ConnectionUrl for the SP admin center. I have the PnP powershell module installed in the PS 7.2 location.

image

image

  1. Would it be possible to add a debug mode option which outputs more information to the terminal? Verbose doesn't seem to do much.

No Automation support for MSCommerce Module

I have tried using token issued by my own app, but even if it has admin privileges it doesn't seem to be working.
What are the plans to allow Certificate Based Authentication or AppID based Oauth logins. The PowerShell gallery has deploy to azure automation, but how will you manage the prompt. Basic auth isn't something we should be doing as we can see in the workarounds so far.

$oAuthUri = "https://login.microsoftonline.com/$TenantId/oauth2/token"

Is there a way we can directly query the graph endpoint, to get what we need.

$baseUri = "https://licensing.m365.microsoft.com"
$restPath = "$baseUri/v1.0/policies"

Invoke-RestMethod : The remote server returned an error: (403) Forbidden.
At line:33 char:16

  • $response = Invoke-RestMethod `
  •            ~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
    • FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

References:
https://www.powershellgallery.com/packages/MSCommerce/1.8
https://docs.microsoft.com/en-us/microsoft-365/commerce/subscriptions/allowselfservicepurchase-powershell?view=o365-worldwide
https://docs.microsoft.com/en-us/microsoft-365/commerce/subscriptions/manage-self-service-purchases-admins?view=o365-worldwide

New connection to MSCommerce · Issue #46 - GitHub
Providing scripted credentials or PSSession ... - GitHub

Test-MSCloudLogin should actually test for all workloads

In some workloads such as AzureAD, Test-MSCloudLogin no longer verifies if we already have a valid login session to the workload before prompting for credentials; it just prompts regardless. We should reincorporate the core test functionality the module originally had.

Error: Intune Workload: Update-MSGraphEnvironment is not recognized as the name of a cmdlet,

When using the the Intune workload I receive the following error

System.Management.Automation.CommandNotFoundException: The term 'Update-MSGraphEnvironment' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
   at System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext, Exception exception)
   at System.Management.Automation.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame frame)
   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
"Error retrieving data:"
at Connect-MSCloudLoginIntune, C:\Program Files\WindowsPowerShell\Modules\MSCloudLoginAssistant\1.0.103\Workloads\Intune.psm1: line 67
at Connect, C:\Program Files\WindowsPowerShell\Modules\MSCloudLoginAssistant\1.0.103\ConnectionProfile.psm1: line 327
at Connect-M365Tenant, C:\Program Files\WindowsPowerShell\Modules\MSCloudLoginAssistant\1.0.103\MSCloudLoginAssistant.psm1: line 206
at New-M365DSCConnection, C:\DevOps\Microsoft365DSC-1\Modules\Microsoft365Dsc\modules\M365DSCUtil.psm1: line 1816
at Get-TargetResource, C:\DevOps\Microsoft365DSC-1\Modules\Microsoft365DSC\DSCResources\MSFT_IntuneWindowsInformationProtectionPolicyWindows10MdmEnrolled\MSFT_IntuneWindowsInformationProtectionPolicyWindows10MdmEnrolled.psm1: line 143
at <ScriptBlock>, <No file>: line 2


If I use the Graph workload I don't have the issue

Connect-MSCloudLoginMSGraphWithUser : The term 'Get-MgContext' is not recognized as the name of a cmdlet,

Connect-MSCloudLoginMSGraphWithUser : The term 'Get-MgContext' is not recognized as the name of a cmdlet,
function, script file, or operable program. Check the spelling of the name, or if a path was included, verify
that the path is correct and try again.
At C:\Program Files\WindowsPowerShell\Modules\MSCloudLoginAssistant\1.1.10\Workloads\MicrosoftGraph.psm1:35
char:9

Tasks

No tasks being tracked yet.

PNP fails to connect for 21Vianet

The PNP.psm1 has in Line 74 a hard check for "onmicrosoft" which makes it to fail for the 21Vianet (China) tenant.

            if ($Global:MSCloudLoginConnectionProfile.PnP.TenantId.Contains('onmicrosoft'))
            {
                $domain = $Global:MSCloudLoginConnectionProfile.PnP.TenantId.Replace('.onmicrosoft.', '-admin.sharepoint.')
                if (-not $Global:MSCloudLoginConnectionProfile.PnP.AdminUrl)
                {
                    $Global:MSCloudLoginConnectionProfile.PnP.AdminUrl = "https://$domain"
                }
                $Global:MSCloudLoginConnectionProfile.PnP.ConnectionUrl = ("https://$domain").Replace('-admin', '')
            }
            else
            {
                throw 'TenantId must be in format contoso.onmicrosoft.com'
            }

PNP Connection Failure with Custom App Registration + non-onmicrosoft UPN

Probably a specific scenario but wanted to report the finding here.

  • Custom Aapp registration for Microsoft Graph PowerShell with Delegation access and using it for M365DSC exports.
  • Using on-prem synced cloud admin account that has UPN in different format than contoso.onmicrosoft.com.

Failing with below error:

`[WARNING] We recommend providing the username in the format of .onmicrosoft.* for the Credential property.
Exporting Microsoft 365 configuration for Components: ODSettings, SPOApp, SPOBrowserIdleSignout, SPOHomeSite, SPOHubSite, SPOOrgAssetsLibrary, SPOSearchManagedProperty, SPOSearchResultSource, SPOSiteDesign, SPOSiteDesignRights, SPOSiteScript, SPOStorageEntity, SPOTenantCdnEnabled, SPOTenantCdnPolicy, SPOTheme

Authentication methods specified:

  • CredentialsWithApplicationId

Connecting to {PnP}...❌
TenantId must be in format contoso.onmicrosoft.com`

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.