Identity.SignIns.ps1
using namespace Microsoft.Graph.PowerShell.Models #MicrosoftGraphInvitation object is in Microsoft.Graph.Identity.SignIns.private.dll function New-GraphInvitation { <# .synopsis Invites an external user to become a guest in Azure AD #> [cmdletbinding(SupportsShouldProcess=$true)] param ( #The email address of the user being invited. #The characters #~ ! $ % ^ & * ( [ { < > } ] ) + = \ / | ; : " " ? , are not permitted #A . or - is permitted except at the beginning or end of the name. A _ is permitted anywhere. [Parameter(Position=0,ValueFromPipeline=$true)] [string]$EmailAddress, #The display name of the user being invited. [string]$DisplayName, #The userType of the user being invited. By default, this is Guest. You can invite as Member if you are a company administrator.' [string]$UserType, #The URL the user should be redirected to once the invitation is redeemed. Required. [string]$RedirectUrl = 'https://mysignins.microsoft.com/', #Indicates whether an email should be sent to the user being invited or not. [switch]$SendInvitationMessage ) ContextHas -WorkOrSchoolAccount -BreakIfNot $settings = @{ 'invitedUserEmailAddress' = $EmailAddress 'sendInvitationMessage' = $SendInvitationMessage -as [bool] 'inviteRedirectUrl' = $RedirectUrl } if ($DisplayName) {$settings['invitedUserDisplayName'] = $DisplayName} if ($UserType) {$settings['invitedUserType'] = $UserType} $webparams = @{ 'Method' = 'POST' 'Uri' = "$GraphUri/invitations" 'Contenttype' = 'application/json' 'Body' = (ConvertTo-Json $settings -Depth 5) 'AsType' = [MicrosoftGraphInvitation] 'ExcludeProperty' = '@odata.context' } Write-Debug $webparams.Body if ($force -or $pscmdlet.ShouldProcess($EmailAddress, 'Invite User')){ try { $u = Invoke-GraphRequest @webparams if ($Passthru ) {return $u } } catch { # xxxx Todo figure out what errors need to be handled (illegal name, duplicate user) $_ } } } function Get-GraphNamedLocation { <# .synopsis Returns named locations used in conditional access #> param ( #The ID or start of the display-name of a Location [Parameter(ValueFromPipeline=$true,Position=0)] $Location = "" ) process { $uri = "$GraphUri/identity/conditionalAccess/namedlocations" foreach ($l in $Location) { if ($l -match $GUIDRegex) { $response = Invoke-GraphRequest "$uri/$l" -PropertyNotMatch '@odata' } elseif ($l) { $response = Invoke-GraphRequest -ValueOnly ($uri + "?`$filter=startswith(toLower(displayName),'{0}')" -f $l.ToLower()) } else{ $response = Invoke-GraphRequest -ValueOnly $uri } foreach ($r in $response) { if ($r.isTrusted -is [bool]) { $trusted = $r.isTrusted $null = $r.Remove('isTrusted') } else {$trusted = $null} if ($r.ipRanges) { $ipranges = $(foreach ($ipRange in $r.ipRanges) {$ipRange.cidrAddress}) -join ";" $null = $r.Remove('ipranges') } else {$ipranges = $null} if ($r.countriesAndRegions) { $countries = $r.countriesAndRegions -join ";" $null = $r.Remove('countriesAndRegions') } else {$countries = $null} if ($r.includeUnknownCountriesAndRegions -is [bool]) { $includeUnknown = $r.includeUnknownCountriesAndRegions $null = $r.Remove('includeUnknownCountriesAndRegions') } else {$includeUnknown = $null } $null = $r.remove('@odata.type') New-object -TypeName Microsoft.Graph.PowerShell.Models.MicrosoftGraphNamedLocation -Property $r | Add-Member -PassThru -NotePropertyName IsTrusted -NotePropertyValue $trusted | Add-Member -PassThru -NotePropertyName IpRanges -NotePropertyValue $ipranges | Add-Member -PassThru -NotePropertyName CountriesAndRegions -NotePropertyValue $countries | Add-Member -PassThru -NotePropertyName IncludeUnknownCountriesAndRegions -NotePropertyValue $includeUnknown } } } } function Get-GraphConditionalAccessPolicy { param ( #The ID or start of the display-name of a Policy [Parameter(ValueFromPipeline=$true,Position=0)] $Policy = "" ) process { #needs beta to work when conditions.devices is set (which is marked as preview in the GUI) $uri = "beta/identity/conditionalAccess/policies" foreach ($p in $Policy) { if ($p -match $GUIDRegex) { Invoke-GraphRequest "$uri/$p" -AsType ([MicrosoftGraphConditionalAccessPolicy]) -PropertyNotMatch '@odata' } elseif ($P) { $uri += ("?`$filter=startswith(toLower(displayName),'{0}')" -f $p.ToLower()) Invoke-GraphRequest -ValueOnly $uri -AsType ([MicrosoftGraphConditionalAccessPolicy]) } else{ Invoke-GraphRequest -ValueOnly $uri -AllValues -AsType ([MicrosoftGraphConditionalAccessPolicy]) } } } } function Expand-GraphConditionalAccessPolicy { param ( #The ID or start of the display-name of a Policy [Parameter(ValueFromPipeline=$true,Position=0)] $Policy = "" ) begin { $locations = @{} Invoke-GraphRequest "$GraphUri/identity/conditionalAccess/namedlocations" -ValueOnly -AllValues | ForEach-Object {$locations[$_.id] = $_.DisplayName} $dirRoleTemplates = @{} ; Invoke-GraphRequest -Uri "$GraphUri/directoryroletemplates/" -ValueOnly -AllValues | ForEach-Object {$dirRoleTemplates[$_.id] = $_.DisplayName} $servicePrincipals = @{} Invoke-GraphRequest -Uri "$GraphUri/servicePrincipals/" -ValueOnly -AllValues | ForEach-Object {$servicePrincipals[$_.id] = $_.Displayname} $dirobjs = @{} $result = @() function resolveDirObj { param ( [Parameter(ValueFromPipeline=$true)] $D ) process { if ($D -notmatch $GUIDRegex ) {return $d} elseif (-not $dirobjs.ContainsKey($D)) { $dirobjs[$d] = (Invoke-GraphRequest "$GraphUri/directoryObjects/$d").displayname } $dirobjs[$d] } } function tranlasteGUID { param ( [Parameter(ValueFromPipeline=$true)]$G, [Parameter(Position=0)]$hash ) process {if ($g -notmatch $GUIDRegex ) {return $g} else {$hash[$g]}} } } process { Get-GraphConditionalAccessPolicy @PSBoundParameters | Select-Object -Property DisplayName , Description, State, @{n='IncludeUsers'; e={($_.Conditions.Users.IncludeUsers | resolveDirObj ) -join '; '}}, @{n='ExcludeUsers'; e={($_.Conditions.Users.ExcludeUsers | resolveDirObj ) -join '; '}}, @{n='IncludeGroups'; e={($_.Conditions.Users.IncludeGroups | resolveDirObj ) -join '; '}}, @{n='ExcludeGroups'; e={($_.Conditions.Users.ExcludeGroups | resolveDirObj ) -join '; '}}, @{n='IncludeRoles'; e={($_.Conditions.Users.IncludeRoles | tranlasteGUID $dirRoleTemplates) -join '; '}}, @{n='ExcludeRoles'; e={($_.Conditions.Users.ExcludeRoles | tranlasteGUID $dirRoleTemplates) -join '; '}}, @{n='IncludeLocations'; e={($_.Conditions.Locations.IncludeLocations | translateGuid $locations) -join '; '}}, @{n='ExcludeLocations'; e={($_.Conditions.Locations.ExcludeLocations | translateGuid $locations) -join "; "}}, @{n='IncludeApplications'; e={($_.Conditions.Applications.IncludeApplications | tranlasteGUID $servicePrincipals) -join '; '}}, @{n='ExcludeApplications'; e={($_.Conditions.Applications.ExcludeApplications | tranlasteGUID $servicePrincipals) -join '; '}}, @{n='IncludeUserActions'; e={ $_.Conditions.Applications.IncludeUserActions -join '; '}}, @{n='IncludeDevices'; e={ $_.Conditions.Devices.IncludeDevices -join '; '}}, @{n='ExcludeDevices'; e={ $_.Conditions.Devices.ExcludeDevices -join '; '}}, @{n='ClientAppTypes'; e={ $_.Conditions.ClientAppTypes -join '; '}}, @{n='IncludePlatforms'; e={ $_.Conditions.Platforms.IncludePlatforms -join '; '}}, @{n='ExcludePlatforms'; e={ $_.Conditions.Platforms.EccludePlatforms -join '; '}}, @{n='AppEnforcedRestrictions'; e={ $_.SessionControls.ApplicationEnforcedRestrictions.IsEnabled}}, @{n='PersistentBrowser'; e={ if ($_.SessionControls.PersistentBrowser.isenabled) { $_.SessionControls.PersistentBrowser.Mode} else {$null}}}, @{n='CloudAppSecurity'; e={ if ($_.SessionControls.CloudAppSecurity.isenabled) { $_.SessionControls.CloudAppSecurity.CloudAppSecurityType} else {$null}}} , @{n='SignInFrequency'; e={ if ($_.SessionControls.SignInFrequency.isenabled) { $_.SessionControls.SignInFrequency.Value + " " + $_.SessionControls.SignInFrequency.Type } else {$null}}} } } |