Skip to content

Instantly share code, notes, and snippets.

@SMSAgentSoftware
Last active January 28, 2025 00:49
Show Gist options
  • Save SMSAgentSoftware/c40cce531f0ffaeb81ff8f40da687e5f to your computer and use it in GitHub Desktop.
Save SMSAgentSoftware/c40cce531f0ffaeb81ff8f40da687e5f to your computer and use it in GitHub Desktop.

Revisions

  1. SMSAgentSoftware created this gist Nov 26, 2024.
    102 changes: 102 additions & 0 deletions Activate-SecuredPIMRole.ps1
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,102 @@
    # Use this code to retrieve all Conditional Access policies that use authentication context from Microsoft Graph
    Connect-MgGraph
    $policies = Get-MgIdentityConditionalAccessPolicy | Where-Object { $_.Conditions.Applications.IncludeAuthenticationContextClassReferences -ne $null }
    $policies | ForEach-Object {
    [PSCustomObject]@{
    DisplayName = $_.DisplayName
    State = $_.State
    AuthContext = $_.Conditions.Applications.IncludeAuthenticationContextClassReferences
    }
    } | Format-Table -AutoSize



    # Define your application details
    $clientId = "14d82eec-204b-4c2f-b7e8-296a70dab67e" # The app Id used by the Graph SDK
    $tenantId = "<Your tenant Id here>"
    $redirectUri = "http://localhost:8080"
    $scope = "https://graph.microsoft.com/.default"
    $claimValue = "c1" # The value of the authentication context claim from the conditional access policy

    # Encode the additional claims
    $additionalClaims = [ordered]@{"access_token" = [ordered]@{"acrs" = [ordered]@{"essential" = $true; "value" = $claimValue}}}
    $encodedClaims = [System.Web.HttpUtility]::UrlEncode(($additionalClaims | ConvertTo-Json -Compress))

    # Generate the authorization URL
    $authUrl = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/authorize?client_id=$clientId&response_type=code&redirect_uri=$redirectUri&response_mode=query&scope=$scope&claims=$encodedClaims"

    # Start a local HTTP listener to capture the authorization code
    $listener = New-Object System.Net.HttpListener
    $listener.Prefixes.Add($redirectUri + "/")
    $listener.Start()

    # Open the authorization URL in the default browser
    Start-Process $authUrl

    # Wait for the authorization response
    Write-Host "Waiting for authorization response..."
    $context = $listener.GetContext()
    $response = $context.Response
    $request = $context.Request

    # Extract the authorization code from the query parameters
    $authCode = $request.QueryString["code"]

    if ($authCode)
    {
    $responseString = "Authorization code received. You can close this window."
    }
    else
    {
    $responseString = "No authorization code received. Please try again."
    }

    # Send a response to the browser
    $buffer = [System.Text.Encoding]::UTF8.GetBytes($responseString)
    $response.ContentLength64 = $buffer.Length
    $response.OutputStream.Write($buffer, 0, $buffer.Length)
    $response.OutputStream.Close()

    # Stop the listener
    $listener.Stop()
    $listener.Dispose()

    # Get Access Token
    $Body = @{
    grant_type = 'authorization_code'
    client_id = $ClientID
    scope = $Scope
    code = $AuthCode
    redirect_uri = $RedirectUri
    claims = '{"access_token":{"xms_cc":{"values":["cp1"]}}}' # Request the xms_cc optional claim with the value cp1
    }
    $Response = Invoke-RestMethod "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token" -Method POST -Body $Body
    $accessToken = $Response.access_token


    # Connect to Microsoft Graph with the access token
    $graphToken = $accessToken | ConvertTo-SecureString -AsPlainText -Force
    $null = Disconnect-MgGraph -ErrorAction SilentlyContinue
    Connect-MgGraph -NoWelcome -AccessToken $graphToken

    # Activate a PIM role assignment
    $subjectId = "6981d298-1234-5678-9abc-9c7ddee0a65b" # The Entra object Id of the user to activate the role assignment for
    $roleDefinitionId = "2b745bdf-0803-4d80-aa65-822c4493daac" # The role definition Id of the role assignment to activate (eg "Office Apps Administrator")
    $assignmentDuration = "PT1H" # The duration of the role assignment in ISO 8601 format (1 hour)
    $StartDateTime = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffZ")
    $params = @{
    "PrincipalId" = $SubjectID
    "RoleDefinitionId" = $roleDefinitionId
    "Justification" = "Activate assignment"
    "DirectoryScopeId" = "/"
    "Action" = "SelfActivate"
    "ScheduleInfo" = @{
    "StartDateTime" = $StartDateTime
    "Expiration" = @{
    "Type" = "AfterDuration"
    "Duration" = $AssignmentDuration
    }
    }
    }

    $response = New-MgRoleManagementDirectoryRoleAssignmentScheduleRequest -BodyParameter $params