KnowIT.MSGraph.psm1
|
#region === Source functions === ### Source file: 'Add-EntraDirectoryRoleMember.ps1' ### function Add-EntraDirectoryRoleMember { [Alias('Add-AzAdDirectoryRoleMember')] param( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$PrincipalId, [Parameter(Mandatory, ParameterSetName = 'RoleId')] [ValidateNotNullOrEmpty()] [string]$Id, [Parameter(Mandatory, ParameterSetName = 'RoleTemplateId')] [ValidateNotNullOrEmpty()] [string]$RoleTemplateId, [Parameter(Mandatory, ParameterSetName = 'RoleName')] [Alias('RoleName')] [string]$Name ) try { Update-CallerPreference [void]$PSBoundParameters.Remove('PrincipalId') $role = Get-EntraDirectoryRole @PSBoundParameters if(!$role) { throw "No esta definido el $($PSCmdlet.ParameterSetName) [$($Id + $RoleTemplateId + $Name)] en el Directorio '$((Get-AzContext).Tenant.Name)'" } $request = @{ principalId = $PrincipalId roleDefinitionId = $role.templateId directoryScopeId = '/' } Invoke-MsGraph 'roleManagement/directory/roleAssignments' -Method POST -Body $request -ErrorAction Stop } catch { $PSCmdlet.WriteError($_) } } ### Source file: 'ConvertFrom-MsGraphResponse.ps1' ### filter ConvertFrom-MsGraphResponse { param( [Parameter(Mandatory, ValueFromPipeline)] [PSTypeNameAttribute('KnowIT.MsGraph.Response')] $InputObject ) $statusCode = $InputObject.StatusCode if($InputObject.Success) { return $InputObject.Value } if($statusCode -eq 404) { Write-Verbose "Response MsGraph: No se obtuvo ningun registro" return } Write-Error -ErrorRecord ([Management.Automation.ErrorRecord]::new( [Exception]$InputObject.Error.message, $InputObject.Error.code, [Management.Automation.ErrorCategory]::InvalidResult, $InputObject)) } ### Source file: 'Get-EntraAppExpiringCreds.ps1' ### function Get-EntraAppExpiringCreds { param( [int]$Days = 15 ) try { Update-CallerPreference $dateLimit = (Get-Date).AddDays($Days) Invoke-MsGraph 'applications?$select=id,appId,displayName,passwordCredentials,keyCredentials' -ErrorAction Stop | Map-Object { $app = $_ foreach($credential in $app.passwordCredentials + $app.keyCredentials) { if($credential -and $credential.endDateTime -le $dateLimit) { [PSCustomObject]@{ Name = $app.displayName ApplicationId = $app.appId ObjectId = $app.id Credential = $credential.customKeyIdentifier ? $credential.displayName : 'Password' Expiration = $credential.endDateTime } } } } } catch { $PSCmdlet.WriteError($_) } } ### Source file: 'Get-EntraApplication.ps1' ### function Get-EntraApplication { param ( [Parameter(Position = 0, ParameterSetName = 'ById')] [ValidateNotNullOrEmpty()] [Alias('ObjectId')] [string]$Id, [Parameter(Mandatory, ParameterSetName = 'ByApplicationId')] [ValidateNotNullOrEmpty()] [string]$ApplicationId, [Parameter(Mandatory, ParameterSetName = 'ByUniqueName')] [ValidateNotNullOrEmpty()] [string]$UniqueName, [Parameter(Mandatory, ParameterSetName = 'ByServicePrincipal')] [ValidateNotNullOrEmpty()] [string]$ServicePrincipalId ) try { Update-CallerPreference Write-Verbose "Procesando parametros: '$($PSCmdlet.ParameterSetName)'" switch ($PSCmdlet.ParameterSetName) { 'ById' { Invoke-MsGraph "applications/$Id" break } 'ByApplicationId' { Invoke-MsGraph "applications(appId='$ApplicationId')" break } 'ByUniqueName' { Invoke-MsGraph "applications(uniqueName='$UniqueName')" break } 'ByServicePrincipal' { $sp = Invoke-MsGraph "servicePrincipals/$ServicePrincipalId" if($sp) { Invoke-MsGraph "applications(appId='$($sp.appId)')" } break } } } catch { $PSCmdlet.WriteError($_) } } ### Source file: 'Get-EntraDirectoryRole.ps1' ### function Get-EntraDirectoryRole { [CmdletBinding()] [Alias('Get-AzAdDirectoryRole')] param( [Parameter(ParameterSetName = 'RoleId')] [ValidateNotNullOrEmpty()] [Alias('RoleId')] [string]$Id, [Parameter(Mandatory, ParameterSetName = 'RoleTemplateId')] [ValidateNotNullOrEmpty()] [string]$RoleTemplateId, [Parameter(Mandatory, Position = 0, ParameterSetName = 'RoleName')] [ValidateNotNullOrEmpty()] [Alias('DisplayName')] [string]$Name ) try { Update-CallerPreference Write-Verbose "Procesando parametros: '$($PSCmdlet.ParameterSetName)'" switch ($PSCmdlet.ParameterSetName) { 'RoleId' { $path = "directoryRoles/$Id" break } 'RoleTemplateId' { $path = "directoryRoles(roleTemplateId='$RoleTemplateId')" break } 'RoleName' { $path = "directoryRoles?`$filter=displayName eq '$Name'" break } } Invoke-MsGraph $path | Map-Object { [PSCustomObject]@{ id = $_.id templateId = $_.roleTemplateId name = $_.displayName description = $_.description } } } catch { $PSCmdlet.WriteError($_) } } ### Source file: 'Get-EntraDirectoryRoleMembers.ps1' ### function Get-EntraDirectoryRoleMembers { [CmdletBinding(DefaultParameterSetName = 'RoleName')] [Alias('Get-AzAdDirectoryRoleMembers')] param( [Parameter(Mandatory, ParameterSetName = 'RoleId')] [ValidateNotNullOrEmpty()] [Alias('RoleId')] [string]$Id, [Parameter(Mandatory, ParameterSetName = 'RoleTemplateId')] [ValidateNotNullOrEmpty()] [string]$RoleTemplateId, [Parameter(Mandatory, Position = 0, ParameterSetName = 'RoleName')] [ValidateNotNullOrEmpty()] [Alias('DisplayName')] [string]$Name ) try { Update-CallerPreference $roles = Get-EntraDirectoryRole @PSBoundParameters foreach($role in $roles) { Invoke-MsGraph "roleManagement/directory/roleAssignments?`$filter=roleDefinitionId eq '$($role.TemplateId)'&`$expand=principal" | Map-Object { $principal = $_.principal $principalType = $principal.'@odata.type'.Split('.')[-1] #-replace "^(.)", { $_.Groups[1].Value.ToUpper() } $principalName = switch ($principalType) { 'user' { $principal.userPrincipalName break } 'servicePrincipal' { $principal.servicePrincipalNames[0] break } 'group' { $principal.mail ?? $principal.displayName break } default { $principal.displayName } } [PSCustomObject]@{ role = $role.name principalId = $principal.id principalName = $principalName displayName = $principal.displayName roleId = $role.id roleTemplateId = $role.templateId principalType = $principalType enabled = $principalType -eq 'group' ? $true : $principal.accountEnabled assignmentId = $_.id #Pricipal = $_.principal } } } } catch { $PSCmdlet.WriteError($_) } } ### Source file: 'Get-EntraGroup.ps1' ### function Get-EntraGroup { [CmdletBinding()] param ( [Parameter(ParameterSetName = 'ById')] [ValidateNotNullOrEmpty()] [Alias('ObjectId')] [string]$Id, [Parameter(Mandatory, Position = 0, ParameterSetName = 'ByDisplayName')] [ValidateNotNull()] [string]$DisplayName ) try { Update-CallerPreference Write-Verbose "Procesando parametros: '$($PSCmdlet.ParameterSetName)'" switch ($PSCmdlet.ParameterSetName) { 'ById' { Invoke-MsGraph "groups/$Id" } 'ByDisplayName' { Invoke-MsGraph "groups?`$filter=displayName eq '$DisplayName'" } } } catch { $PSCmdlet.WriteError($_) } } ### Source file: 'Get-EntraServicePrincipal.ps1' ### function Get-EntraServicePrincipal { param ( [Parameter(Position = 0, ParameterSetName = 'ById')] [ValidateNotNullOrEmpty()] [Alias('ObjectId')] [string]$Id, [Parameter(Mandatory, ParameterSetName = 'ByApplicationId')] [ValidateNotNullOrEmpty()] [string]$ApplicationId ) try { Update-CallerPreference Write-Verbose "Procesando parametros: '$($PSCmdlet.ParameterSetName)'" switch ($PSCmdlet.ParameterSetName) { 'ById' { Invoke-MsGraph "servicePrincipals/$Id" break; } 'ByApplicationId' { Invoke-MsGraph "servicePrincipals(appId='$ApplicationId')" break; } } } catch { $PSCmdlet.WriteError($_) } } ### Source file: 'Get-EntraUser.ps1' ### function Get-EntraUser { [CmdletBinding()] param ( [Parameter(ParameterSetName = 'ById')] [Alias('ObjectId')] [string]$Id, [Parameter(Mandatory, Position = 0, ParameterSetName = 'ByUPN')] [string]$UserPrincipalName ) try { Update-CallerPreference Write-Verbose "Procesando parametros: '$($PSCmdlet.ParameterSetName)'" switch ($PSCmdlet.ParameterSetName) { 'ById' { Invoke-MsGraph "users/$Id" } 'ByUPN' { Invoke-MsGraph "users?`$filter=userPrincipalName eq '$UserPrincipalName'" } } } catch { $PSCmdlet.WriteError($_) } } ### Source file: 'Grant-EntraAppConsent.ps1' ### function Grant-EntraAppConsent { param( [Parameter(Mandatory)] [string]$ClientId, [Parameter(Mandatory)] [ValidateCount(1, 100)] [string[]]$Scopes, [Alias('API')] [string]$ApplicationId = '00000003-0000-0000-c000-000000000000', # default Microsoft Graph AppId, [Parameter(Mandatory, ParameterSetName = 'ByUser')] [string]$UserPrincipalName, [Parameter(Mandatory, ParameterSetName = 'AllUsers')] [switch]$AllUsers ) try { Update-CallerPreference $clientSp = GetAppServicePrincipal -ApplicationId $ClientId $applicationSp = GetAppServicePrincipal -ApplicationId $ApplicationId $params = @{ clientId = $clientSp.Id resourceId = $applicationSp.Id scope = $Scopes -join ' ' } if($PSCmdlet.ParameterSetName -eq 'AllUsers') { $params.consentType = 'AllPrincipals' Write-Verbose "Concede permisos [$Scopes] de '$($applicationSp.displayName)' a todos los usuarios de la aplicación '$($clientSp.displayName)'" } elseif($PSCmdlet.ParameterSetName -eq 'ByUser') { $principalId = (Get-EntraUser -UserPrincipalName $UserPrincipalName).Id ThrowIfNotFound $principalId $UserPrincipalName -PrincipalType 'Usuario' $params.consentType = 'Principal' $params.principalId = $principalId Write-Verbose "Concede permisos [$Scopes] de '$($applicationSp.displayName)' al usuario $UserPrincipalName en la aplicación '$($clientSp.displayName)'" } Invoke-MsGraph 'oauth2PermissionGrants' -Method Post -Body $params -ErrorAction Stop } catch { $PSCmdlet.WriteError($_) } } ### Source file: 'Grant-EntraAppRoleAssignment.ps1' ### function Grant-EntraAppRoleAssignment { param ( [Parameter(Mandatory, ParameterSetName = 'Id')] [Alias('PrincipalId')] [string]$Id, [Parameter(Mandatory, ParameterSetName = 'User')] [string]$UserPrincipalName, [Parameter(Mandatory, ParameterSetName = 'Group')] [string]$GroupName, [Parameter(Mandatory, ParameterSetName = 'App')] [string]$ClientId, [Parameter(Mandatory)] [ValidateCount(1, 100)] [string[]]$Roles, [Alias('API')] [string]$ApplicationId = '00000003-0000-0000-c000-000000000000' # default Microsoft Graph AppId, ) try { Update-CallerPreference $applicationSp = GetAppServicePrincipal -ApplicationId $ApplicationId -Properties 'appRoles' switch ($PSCmdlet.ParameterSetName) { 'Id' { $principal = Invoke-MsGraph "directoryObjects/$Id" ThrowIfNotFound $principal $Id $allowedTypes = 'servicePrincipal', 'user', 'group' $principalType = $principal.'@odata.type'.Split('.')[-1] if($principalType -notin $allowedTypes) { throw "El objecto a asignar es de tipo '$pricipalType'. Solo estan permitidos los tipos ($($allowedTypes -join ', '))" } $principalId = $principal.id $memberType = $principalType -eq 'servicePrincipal' ? 'Application' : 'User' break } 'App' { $principalId = (GetAppServicePrincipal -ApplicationId $ClientId).id ThrowIfNotFound $principalId $ClientId -PrincipalType 'ApplicationId' $memberType = 'Application' break } 'User' { $principalId = (Get-EntraUser -UserPrincipalName $UserPrincipalName).id ThrowIfNotFound $principalId $UserPrincipalName -PrincipalType 'Usuario' $memberType = 'User' break } 'Group' { $group = Get-EntraGroup -DisplayName $GroupName if(!$group.securityEnabled) { throw "El grupo [$GroupName] no existe o no tiene habilitada la propiedad 'SecurityEnabled'" } $principalId = $group.id $memberType = 'User' break } } $appRoles = $applicationSp.appRoles.Where( { $_.value -in $Roles -and $_.allowedMemberTypes -contains $memberType }) if(!$appRoles) { throw "La Aplicacion [$($applicationSp.displayName)] no contiene ninguno de los roles solicitados" } $path = 'servicePrincipals/{0}/appRoleAssignedTo' -f $applicationSp.id $params = @{ principalId = $principalId resourceId = $applicationSp.id appRoleId = $null # Este valor se asigna por llamada a cada rol } Write-Verbose "Asignando roles [$($appRoles.value -join ', ')] de la aplicacion '$($applicationSp.displayName)' ..." foreach($r in $appRoles) { $params.appRoleId = $r.id $response = Invoke-MsGraph $path -Method Post -Body $params -DetailResponse if(!$response.Success -and $response.Error.additionalErrors.code -eq 'InvalidUpdate') { Write-Warning "El rol [$($r.value)] ya se encuentra asignado." continue } $assign = $response | ConvertFrom-MsGraphResponse [PSCustomObject]@{ principalName = $assign.principalDisplayName principalType = $assign.principalType appRole = $r.value appName = $assign.resourceDisplayName } } } catch { $PSCmdlet.WriteError($_) } } ### Source file: 'Invoke-MsGraph.ps1' ### function Invoke-MsGraph { [CmdletBinding()] [Alias('msgr')] param( [Parameter(Mandatory, Position = 0)] [string]$Path, [ValidateSet('GET', 'POST', 'PATCH', 'PUT', 'DELETE')] [string]$Method = 'GET', [object]$Body, [hashtable]$Headers = @{}, [switch]$DetailResponse, [switch]$Beta ) try { Update-CallerPreference $PSCmdlet -Skip Verbose $token = GetGraphToken $Headers.Authorization = "Bearer $token" $path = $Path.TrimStart('/') $version = $Beta ? 'beta' : 'v1.0' $restParams = @{ Method = $Method Uri = "https://graph.microsoft.com/$version/$path" Headers = $Headers Body = $Body ? (ConvertTo-Json $Body -Depth 4) : $null ContentType = 'application/json' Verbose = $false } Write-Verbose "Request MsGraph: $($restParams.Method.ToUpper()) /$version/$path" if($Body) { Write-Debug "Body: $($restParams.Body)" } $result = Invoke-RestMethod @restParams -SkipHttpErrorCheck -StatusCodeVariable statusCode if(!$result.error) { Write-Verbose "Response MsGraph: [$statusCode] $([Net.HttpStatusCode]$statusCode)" $response = [PSCustomObject]@{ PSTypeName = 'KnowIT.MsGraph.Response' Success = $true StatusCode = $statusCode Value = $result.Value ?? $result } } else { Write-Debug 'Procesando error en la respuesta del API...' $response = [PSCustomObject]@{ PSTypeName = 'KnowIT.MsGraph.Response' Success = $false StatusCode = $statusCode Error = [ordered]@{ code = $result.error.innerError?.code ?? $result.error.code message = $result.error.innerError?.message ?? $result.error.message details = $result.error.innerError | Select-Object -Exclude 'code', 'message', 'details' additionalErrors = ($result.error.details ?? @()) + ($result.error.innerError.details ?? @()) } } Write-Verbose "Response MsGraph: [$statusCode] $($response.Error.code) - $($response.Error.message)" } if($DetailResponse) { $response } else { $response | ConvertFrom-MsGraphResponse } } catch { $PSCmdlet.WriteError($_) } } ### Source file: 'Register-EntraApplication.ps1' ### function Register-EntraApplication { param ( [Parameter(Mandatory, Position = 0)] [ValidatePattern('^[a-z]+(-[a-z0-9]+)*$')] [string]$Name, [string]$DisplayName = $Name, [hashtable]$AppProperties = @{}, [switch]$WithServicePrincipal ) try { Update-CallerPreference $AppProperties.uniqueName = $Name.ToLower() $AppProperties.displayName = $DisplayName $graphParams = @{ Method = 'PATCH' Path = "applications(uniqueName='$Name')" Body = $AppProperties Headers = @{ Prefer = 'create-if-missing' } } $graphResult = Invoke-MsGraph @graphParams -DetailResponse $app = switch ($graphResult.StatusCode) { 201 { Write-Verbose "Aplicacion [$Name] creada exitosamente (AppId = '$($graphResult.Value.appId)')" $graphResult.Value break } 204 { Write-Verbose "Aplicacion [$Name] existente. Actualizada de manera exitosa!" Invoke-MsGraph $graphParams.Path break } 400 { foreach($e in $graphResult.Error.additionalErrors) { if($e.code -eq 'ObjectConflict' -and $e.target -eq 'uniqueName') { #TODO: Recuperar? Eliminar permanentemente throw 'La aplicacion ha sido eliminada??' } } $graphResult | ConvertFrom-MsGraphResponse } default { # En este caso el resultado solo puede ser no exitoso por lo que se generaria el un error de terminacion $graphResult | ConvertFrom-MsGraphResponse throw # Realmente nunca deberia llegar aqui } } if($WithServicePrincipal){ $sp = RegisterAppServicePrincipal $app.appId $app | Add-Member -MemberType NoteProperty servicePrincipalId -Value $sp.id } return $app } catch { $PSCmdlet.WriteError($_) } } ### Source file: 'Register-EntraServicePrincipal.ps1' ### function Register-EntraServicePrincipal { [CmdletBinding()] param ( [Parameter(Mandatory, ParameterSetName = 'AppId')] [string]$ApplicationId, [Parameter(Mandatory, Position = 0, ParameterSetName = 'Name')] [string]$Name, [Parameter(ParameterSetName = 'Name')] [hashtable]$AppProperties = @{} ) try { Update-CallerPreference if($PSCmdlet.ParameterSetName -eq 'Name') { $appName = $Name.Replace('/', '-').ToLower() Write-Verbose "Registra primeramente la aplicación asociada [$appName]" $app = Register-EntraApplication $appName -DisplayName $Name -AppProperties $AppProperties $ApplicationId = $app.appId } RegisterAppServicePrincipal $ApplicationId } catch { $PSCmdlet.WriteError($_) } } ### Source file: 'Remove-EntraDirectoryRoleMember.ps1' ### function Remove-EntraDirectoryRoleMember { [Alias('Remove-AzAdDirectoryRoleMember')] param( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$PrincipalId, [Parameter(Mandatory, ParameterSetName = 'RoleId')] [ValidateNotNullOrEmpty()] [string]$Id, [Parameter(Mandatory, ParameterSetName = 'RoleTemplateId')] [ValidateNotNullOrEmpty()] [string]$RoleTemplateId, [Parameter(Mandatory, ParameterSetName = 'RoleName')] [Alias('RoleName')] [string]$Name ) try { Update-CallerPreference [void]$PSBoundParameters.Remove('PrincipalId') $role = Get-EntraDirectoryRole @PSBoundParameters if(!$role) { throw "No esta definido el $($PSCmdlet.ParameterSetName) [$($Id + $RoleTemplateId + $Name)] en el Directorio '$((Get-AzContext).Tenant.Name)'" } $roleAssignment = Invoke-MsGraph "roleManagement/directory/roleAssignments?`$select=id&`$filter=principalId eq '$PrincipalId' and roleDefinitionId eq '$($role.templateId)'" if(!$roleAssignment.id) { throw "El PrincipalId '$PrincipalId' no tiene asignado el rol [$($role.name)]" } Invoke-MsGraph "roleManagement/directory/roleAssignments/$($roleAssignment.id)" -Method DELETE } catch { $PSCmdlet.WriteError($_) } } ### Source file: 'Set-EntraAppCredential.ps1' ### function Set-EntraAppCredential { [CmdletBinding()] param( [Parameter(Mandatory, Position = 0, ParameterSetName = 'ByApplicationId')] [ValidateNotNullOrEmpty()] [string]$ApplicationId, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$Name, [int]$ExpireMonths = 12 ) try { Update-CallerPreference $app = GetApplication $ApplicationId -Properties 'passwordCredentials' $removePath = "applications/$($app.id)/removePassword" $app.passwordCredentials. Where({ $_.displayName -eq $Name }). ForEach({ Invoke-MsGraph $removePath -Body @{ keyId = $_.keyId } -Method POST }) $credential = @{ passwordCredential = @{ displayName = $Name endDateTime = [datetime]::UtcNow.AddMonths($ExpireMonths).ToString('o') } } Write-Verbose "Generando nueva credencial '$Name'" Invoke-MsGraph "applications/$($app.id)/addPassword" -Body $credential -Method POST } catch { $PSCmdlet.WriteError($_) } } ### Source file: 'Set-EntraAppFederatedIdentity.ps1' ### function Set-EntraAppFederatedIdentity { param ( [Parameter(Mandatory, Position = 0, ParameterSetName = 'ByApplicationId')] [ValidateNotNullOrEmpty()] [string]$ApplicationId, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$Name, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$Issuer, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$Subject, [Parameter()] [ValidateNotNullOrEmpty()] [string[]]$Audience = @('api://AzureADTokenExchange') ) try { Update-CallerPreference $app = GetApplication $ApplicationId $path = "applications/$($app.id)/federatedIdentityCredentials(name='$Name')" $body = @{ name = $Name issuer = $Issuer subject = $Subject audiences = $Audience } $null = Invoke-MsGraph $path -Method PATCH -Body $body -Headers @{ Prefer = 'create-if-missing' } } catch { $PSCmdlet.WriteError($_) } } ### Source file: 'Applications.ps1' ### function GetApplication ([string]$ApplicationId, [string[]]$Properties) { $propList = ('id', 'appId', 'displayName' + $Properties) -join ',' $app = Invoke-MsGraph "applications(appId='$ApplicationId')?`$select=$propList" if(!$app) { $azureCtx = Get-AzContext throw "No se encontro la aplicación [$ApplicationId] en el directorio '$($azureCtx.Tenant.Name)'" } $app } ### Source file: 'errors.ps1' ### function ThrowIfNotFound ($Principal, [string]$PrincipalId, [string]$PrincipalType = 'Objeto') { if(!$Principal) { $azureCtx = Get-AzContext $tenant = $azureCtx.Tenant.Name ?? $azureCtx.Tenant.TenantId throw "No se encontro el $PrincipalType [$PrincipalId] en el directorio '$tenant'" } } ### Source file: 'KnowIT.ModuleHelpers.ps1' ### function Update-CallerPreference { # https://devblogs.microsoft.com/scripting/weekend-scripter-access-powershell-preference-variables/ param( [ValidateNotNull()] [PSTypeName('System.Management.Automation.PSScriptCmdlet')]$ScriptCmdlet = (Get-Variable PSCmdlet -Scope 1 -ValueOnly), [ValidateSet('ErrorAction', 'Warning', 'Verbose', 'Debug', 'Information', 'Progress', 'Confirm', 'WhatIf')] [string[]]$Skip ) $commonParameters = 'ErrorAction', 'Warning', 'Verbose', 'Debug', 'Information', 'Progress', 'Confirm', 'WhatIf' $invocation = $ScriptCmdlet.MyInvocation $commandDebug = $invocation.BoundParameters.ContainsKey('Debug') Write-Debug "Updating [$($invocation.MyCommand)] Preference variables:" -Debug:$commandDebug foreach($p in $commonParameters) { if($invocation.BoundParameters.ContainsKey($p)) { continue } $var = "${p}Preference" if($p -eq 'ErrorAction') { $val = 'Stop' $scope = 'Forced' } elseif($p -in $Skip) { $val = Get-Variable -Scope Global -Name $var -ValueOnly $scope = 'Global' } else { $val = $ScriptCmdlet.GetVariableValue($var) $scope = 'Caller' } Write-Debug " (From $scope scope) $var = $val " -Debug:$commandDebug Set-Variable -Scope 1 -Name $var -Value $val } } function Map-Object { [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseApprovedVerbs', '', Justification = 'Internal functions')] param([scriptblock]$ScriptBlock) begin { $code = "& { process { $ScriptBlock } }" $pipeline = [scriptblock]::Create($code).GetSteppablePipeline() $pipeline.Begin($true) } process { $pipeline.Process($_) } end { $pipeline.End() } } ### Source file: 'ServicePrincipals.ps1' ### function GetAppServicePrincipal ([string]$ApplicationId, [string[]]$Properties) { $propList = ('id', 'appId', 'displayName' + $Properties) -join ',' $servicePrincipal = Invoke-MsGraph "servicePrincipals(appId='$ApplicationId')?`$select=$propList" if(!$servicePrincipal) { $azureCtx = Get-AzContext $tenant = $azureCtx.Tenant.Name ?? $azureCtx.Tenant.TenantId throw "No se encontro el Service Principal asociado a la aplicación [$ApplicationId] en el directorio '$tenant'" } $servicePrincipal } function RegisterAppServicePrincipal ([string]$ApplicationId) { $ErrorActionPreference = 'Stop' $azureCtx = Get-AzContext $tenant = $azureCtx.Tenant.Name ?? $azureCtx.Tenant.TenantId $sp = Invoke-MsGraph "servicePrincipals(appId='$ApplicationId')" if(!$sp) { Write-Verbose "Registrando nuevo Service Principal para la aplicación [$ApplicationId] en directorio '$tenant'..." $sp = Invoke-MsGraph 'servicePrincipals' -Method POST -Body @{ appId = $ApplicationId } } else { Write-Verbose "Ya existe el Service Principal asignado a la aplicación [$($sp.displayName)] en el directorio '$tenant'" } return $sp } ### Source file: 'Tokens.ps1' ### function GetGraphToken { $token = Get-AzAccessToken -ResourceUrl 'https://graph.microsoft.com' -AsSecureString -Debug:$false ConvertFrom-SecureString $token.Token -AsPlainText } #endregion |