AzureCommonStuff.psm1
function Connect-AzAccount2 { <# .SYNOPSIS Function for connecting to Azure using Connect-AzAccount command (Az.Accounts module). .DESCRIPTION Function for connecting to Azure using Connect-AzAccount command (Az.Accounts module). In case there is already existing connection, stop. .PARAMETER credential Credentials (User or App) for connecting to Azure. For App credentials tenantId must be set too! .PARAMETER servicePrincipal Switch for using App/Service Principal authentication instead of User auth. .PARAMETER tenantId Azure tenant ID. Mandatory when App authentication is used . .EXAMPLE Connect-AzAccount2 Authenticate to Azure interactively using user credentials. Doesn't work for accounts with MFA! .EXAMPLE $credential = get-credential Connect-AzAccount2 -credential $credential Authenticate to Azure using given user credentials. Doesn't work for accounts with MFA! .EXAMPLE $credential = get-credential Connect-AzAccount2 -servicePrincipal -credential $credential -tenantId 1234-1234-1234 Authenticate to Azure using given app credentials (service principal). .NOTES Requires module Az.Accounts. #> [CmdletBinding()] param ( [System.Management.Automation.PSCredential] $credential, [switch] $servicePrincipal, [string] $tenantId = $_tenantId ) if (Get-AzContext) { Write-Verbose "Already connected to Azure" return } else { if ($servicePrincipal -and !$tenantId) { throw "When servicePrincipal auth is used tenantId has to be set" } $param = @{} if ($servicePrincipal) { $param.servicePrincipal = $true } if ($tenantId) { $param.tenantId = $tenantId } if ($credential) { $param.credential = $credential } Connect-AzAccount @param } } function Connect-PnPOnline2 { <# .SYNOPSIS Proxy function for Connect-PnPOnline with some enhancements like: automatic MFA auth if MFA detected, skipping authentication if already authenticated etc. .DESCRIPTION Proxy function for Connect-PnPOnline with some enhancements like: automatic MFA auth if MFA detected, skipping authentication if already authenticated etc. .PARAMETER credential Credential object you want to use to authenticate to Sharepoint Online .PARAMETER appAuth Switch for using application authentication instead of the user one. .PARAMETER asMFAUser Switch for using user with MFA enabled authentication (i.e. interactive auth) .PARAMETER url Your sharepoint online url ("https://contoso-admin.sharepoint.com") .EXAMPLE Connect-PnPOnline2 Connect to Sharepoint Online using user interactive authentication. .EXAMPLE Connect-PnPOnline2 -asMFAUser Connect to Sharepoint Online using (MFA-enabled) user interactive authentication. .EXAMPLE Connect-PnPOnline2 -appAuth Connect to Sharepoint Online using application interactive authentication. .EXAMPLE Connect-PnPOnline2 -appAuth -credential $cred Connect to Sharepoint Online using application non-interactive authentication. .EXAMPLE Connect-PnPOnline2 -credential $cred Connect to Sharepoint Online using (non-MFA enabled!) user non-interactive authentication. .NOTES Requires Pnp.PowerShell module. #> [CmdletBinding()] param ( [System.Management.Automation.PSCredential] $credential, [switch] $appAuth, [switch] $asMFAUser, [ValidateNotNullOrEmpty()] [string] $url = $_SPOConnectionUri ) if (!$url) { throw "Url parameter is not defined. It should contain your sharepoint URL (for example https://contoso-admin.sharepoint.com)" } if ($appAuth -and $asMFAUser) { Write-Warning "asMFAUser switch cannot be used with appAuth. Ignoring asMFAUser." $asMFAUser = $false } if ($credential -and $asMFAUser) { Write-Warning "When logging using MFA-enabled user, credentials cannot be passed i.e. it has to be interactive login" $credential = $null } try { Write-Verbose "Already connected to Sharepoint" $null = Get-PnPConnection -ea Stop } catch { Write-Verbose "Connecting to Sharepoint" if ($credential -and !$appAuth) { try { Connect-PnPOnline -Url $url -Credentials $credential -ea Stop } catch { if ($_ -match "you must use multi-factor authentication to access") { Write-Error "Account $($credential.UserName) has MFA enabled, therefore interactive logon is needed" Connect-PnPOnline -Url $url -Interactive -ForceAuthentication } else { throw $_ } } } elseif ($credential -and $appAuth) { Connect-PnPOnline -Url $url -ClientId $credential.UserName -ClientSecret $credential.GetNetworkCredential().password } else { # credential is missing if ($asMFAUser) { Connect-PnPOnline -Url $url -Interactive -ForceAuthentication } elseif ($appAuth) { $credential = Get-Credential -Message "Using App auth. Enter ClientId and ClientSecret." Connect-PnPOnline -Url $url -ClientId $credential.UserName -ClientSecret $credential.GetNetworkCredential().password } else { Connect-PnPOnline -Url $url } } } } function New-AzureDevOpsAuthHeader { <# .SYNOPSIS Function for getting authentication header for web requests against Azure DevOps. .DESCRIPTION Function for getting authentication header for web requests against Azure DevOps. Function uses MSAL to authenticate (requires MSAL.PS module). .EXAMPLE $header = New-AzureDevOpsAuthHeader Invoke-WebRequest -Uri $uri -Headers $header .NOTES https://docs.microsoft.com/en-us/rest/api/azure/devops/?view=azure-devops-rest-7.1 PowerShell module AzSK.ADO > ContextHelper.ps1 > GetCurrentContext https://stackoverflow.com/questions/56355274/getting-oauth-tokens-for-azure-devops-api-consumption https://stackoverflow.com/questions/52896114/use-azure-ad-token-to-authenticate-with-azure-devops #> [CmdletBinding()] param () # TODO oAuth auth https://github.com/microsoft/azure-devops-auth-samples/tree/master/OAuthWebSample # $msalToken = Get-MsalToken -TenantId $TenantID -ClientId $ClientID -UserCredential $Credential -Scopes ([String]::Concat($($ApplicationIdUri), '/user_impersonation')) -ErrorAction Stop $clientId = "872cd9fa-d31f-45e0-9eab-6e460a02d1f1" # Visual Studio $adoResourceId = "499b84ac-1321-427f-aa17-267ca6975798" # Azure DevOps app ID $msalToken = Get-MsalToken -Scopes "$adoResourceId/.default" -ClientId $clientId if ($msalToken.accessToken) { $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f "", $msalToken.accessToken))) return @{Authorization = "Basic $base64AuthInfo" } } else { throw "Unable to obtain DevOps MSAL token" } } function Start-AzureSync { <# .SYNOPSIS Invoke Azure AD sync cycle command (Start-ADSyncSyncCycle) on the server where 'Azure AD Connect' is installed. .DESCRIPTION Invoke Azure AD sync cycle command (Start-ADSyncSyncCycle) on the server where 'Azure AD Connect' is installed. .PARAMETER Type Type of sync. Initial (full) or just delta. Delta is default. .PARAMETER ADSynchServer Name of the server where 'Azure AD Connect' is installed .EXAMPLE Start-AzureSync -ADSynchServer ADSYNCSERVER Invokes synchronization between on-premises AD and AzureAD on server ADSYNCSERVER by running command Start-ADSyncSyncCycle there. #> [Alias("Sync-ADtoAzure", "Start-AzureADSync")] [cmdletbinding()] param ( [ValidateSet('delta', 'initial')] [string] $type = 'delta', [ValidateNotNullOrEmpty()] [string] $ADSynchServer ) $ErrState = $false do { try { Invoke-Command -ScriptBlock { Start-ADSyncSyncCycle -PolicyType $using:type } -ComputerName $ADSynchServer -ErrorAction Stop | Out-Null $ErrState = $false } catch { $ErrState = $true Write-Warning "Start-AzureSync: Error in Sync:`n$_`nRetrying..." Start-Sleep 5 } } while ($ErrState -eq $true) } Export-ModuleMember -function Connect-AzAccount2, Connect-PnPOnline2, New-AzureDevOpsAuthHeader, Start-AzureSync Export-ModuleMember -alias Start-AzureADSync, Sync-ADtoAzure |