Azure AD PowerShell Commands and Usages (Tips and Tricks) - NETSEC

Latest

Learning, Sharing, Creating

Cybersecurity Memo

Friday, May 26, 2023

Azure AD PowerShell Commands and Usages (Tips and Tricks)

The Azure PowerShell Az module is a rollup module. Installing the Az PowerShell module downloads the generally available modules and makes their cmdlets available for use. (Tips & Tricks)



Related posts:

The current version of Azure PowerShell is 10.0.0. For information about the latest release, see the release notes.


Install Azure AD Related Module


 Set-ExecutionPolicy Unrestricted

Some useful Azure Modules you might want to install:
  • Install-Module AzureAD
  • Install-module AzureADPreview
  • Install-Module Microsoft.Graph -Force
  • Install-Module msonline

Note: If you get any error message while scripting. Please run the following cmdlet. Otherwise, ignore it. 

Install-PackageProvider -Name NuGet -Force
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

Run the following cmdlet to connect to a Microsoft Service Portal:
Connect-MsolService
Connect-AzureAD
ActionScript

How to Install Azure AD and Microsoft Online PowerShell Module


$AzureAdCred = Get-Credential Connect-AzureAD -Credential $AzureAdCred


  1. Select Start > All Programs > Windows PowerShell version > Windows PowerShell.
  2. Type Set-ExecutionPolicy RemoteSigned to set the policy to RemoteSigned.
  3. Type Set-ExecutionPolicy Unrestricted to set the policy to Unrestricted.
  4. Type Get-ExecutionPolicy to verify the current settings for the execution policy.
  5. Type Exit.

Install Azure Az PowerShell Module


Note: https://learn.microsoft.com/en-us/powershell/azure/install-azps-windows?view=azps-10.1.0&tabs=powershell&pivots=windows-psgallery

Installation

Use the Install-Module cmdlet to install the Az PowerShell module:

PowerShell
Install-Module -Name Az -Repository PSGallery -Force

Update the Az PowerShell module

Use Update-Module to update to the latest version of the Az PowerShell module:

PowerShell
Update-Module -Name Az -Force

Updating the Az PowerShell module using Update-Module doesn't remove old versions of the Az PowerShell module from your system.




PS C:\WINDOWS\system32> Login-AzAccount
WARNING: TenantId 'f194erbf-adfe-fffe-9ea7-e43dfff44a4' contains more than one active subscription. First one will be
selected for further use. To select another subscription, use Set-AzContext.
To override which subscription Connect-AzAccount selects by default, use `Update-AzConfig -DefaultSubscriptionForLogin
00000000-0000-0000-0000-000000000000`. Go to https://go.microsoft.com/fwlink/?linkid=2200610 for more information.

Account                 SubscriptionName       TenantId                             Environment
-------                 ----------------       --------                             -----------
[email protected] NetSec Corporate Hosting f194erbf-adfe-fffe-9ea7-e43dfff44a4 AzureCloud

This image has an empty alt attribute; its file name is image-3.png



Azure AD Users Last Sign-in Report

  • To retrieve Azure AD users with their last sign-in details.
  • To generate a CSV report with the result.
Github: https://github.com/mzmaili/Get-AzureADUsersLastSignIn


<#
.SYNOPSIS
    Get-AzureADUsersLastSignIn PowerShell script.
.DESCRIPTION
    Get-AzureADUsersLastSignIn.ps1 is a PowerShell script retrieves Azure AD users with their last sign in date.
.AUTHOR:
    Mohammad Zmaili
.EXAMPLE
    .\Get-AADUserLastSignIn.ps1
      Retrieves all Azure AD users with their last sign in date.
Important Notes:
    > Tenant should have an Azure Active Directory Premium.
    
    > If 'Last Success Signin (UTC)' value is 'N/A', this could be due to one of the following two reasons:
        - The last successful sign-in of a user took place before April 2020.
        - The affected user account was never used for a successful sign-in.
        
#>

function Connect-AzureDevicelogin {
    [cmdletbinding()]
    param( 
        [Parameter()]
        $ClientID = '1950a258-227b-4e31-a9cf-717495945fc2',
        
        [Parameter()]
        [switch]$Interactive,
        
        [Parameter()]
        $TenantID = 'common',
        
        [Parameter()]
        $Resource = "https://graph.microsoft.com/",
        
        # Timeout in seconds to wait for user to complete sign in process
        [Parameter(DontShow)]
        $Timeout = 300
    )
try {
    $DeviceCodeRequestParams = @{
        Method = 'POST'
        Uri    = "https://login.microsoftonline.com/$TenantID/oauth2/devicecode"
        Body   = @{
            resource  = $Resource
            client_id = $ClientId
            redirect_uri = "https://login.microsoftonline.com/common/oauth2/nativeclient"
            #scope = "Directory.Read.All,AuditLog.Read.All"
            scope = "AuditLog.Read.All"
        }
    }
    $DeviceCodeRequest = Invoke-RestMethod @DeviceCodeRequestParams
 
    # Copy device code to clipboard
    $DeviceCode = ($DeviceCodeRequest.message -split "code " | Select-Object -Last 1) -split " to authenticate."
    Set-Clipboard -Value $DeviceCode

    Write-Host "Device code " -ForegroundColor Yellow -NoNewline
    Write-Host $DeviceCode -ForegroundColor Green -NoNewline
    Write-Host "has been copied to the clipboard, please paste it into the opened 'Microsoft Graph Authentication' window, complete the signin, and close the window to proceed." -ForegroundColor Yellow
    Write-Host "Note: If 'Microsoft Graph Authentication' window didn't open,"($DeviceCodeRequest.message -split "To sign in, " | Select-Object -Last 1) -ForegroundColor gray

    # Open Authentication form window
    Add-Type -AssemblyName System.Windows.Forms
    $form = New-Object -TypeName System.Windows.Forms.Form -Property @{ Width = 440; Height = 640 }
    $web = New-Object -TypeName System.Windows.Forms.WebBrowser -Property @{ Width = 440; Height = 600; Url = "https://www.microsoft.com/devicelogin" }
    $web.Add_DocumentCompleted($DocComp)
    $web.DocumentText
    $form.Controls.Add($web)
    $form.Add_Shown({ $form.Activate() })
    $web.ScriptErrorsSuppressed = $true
    $form.AutoScaleMode = 'Dpi'
    $form.text = "Microsoft Graph Authentication"
    $form.ShowIcon = $False
    $form.AutoSizeMode = 'GrowAndShrink'
    $Form.StartPosition = 'CenterScreen'
    $form.ShowDialog() | Out-Null
        
    $TokenRequestParams = @{
        Method = 'POST'
        Uri    = "https://login.microsoftonline.com/$TenantId/oauth2/token"
        Body   = @{
            grant_type = "urn:ietf:params:oauth:grant-type:device_code"
            code       = $DeviceCodeRequest.device_code
            client_id  = $ClientId
        }
    }
    $TimeoutTimer = [System.Diagnostics.Stopwatch]::StartNew()
    while ([string]::IsNullOrEmpty($TokenRequest.access_token)) {
        if ($TimeoutTimer.Elapsed.TotalSeconds -gt $Timeout) {
            throw 'Login timed out, please try again.'
        }
        $TokenRequest = try {
            Invoke-RestMethod @TokenRequestParams -ErrorAction Stop
        }
        catch {
            $Message = $_.ErrorDetails.Message | ConvertFrom-Json
            if ($Message.error -ne "authorization_pending") {
                throw
            }
        }
        Start-Sleep -Seconds 1
    }
    Write-Output $TokenRequest.access_token
}
finally {
    try {
        Remove-Item -Path $TempPage.FullName -Force -ErrorAction Stop
        $TimeoutTimer.Stop()
    }
    catch {
        # We don't care about errors here
    }
}
}

''
'========================================================'
Write-Host '            Azure AD Users Last SignIn Report          ' -ForegroundColor Green 
'========================================================'
''

$accesstoken = Connect-AzureDevicelogin

$AADUsers = @()
$headers = @{ 
            'Content-Type'  = "application\json"
            'Authorization' = "Bearer $accesstoken"
            }

$GraphLink = "https://graph.microsoft.com/beta/users?$"
$GraphLink = $GraphLink + "select=id,userPrincipalName,displayName,accountEnabled,onPremisesSyncEnabled,createdDateTime,signInActivity&`$top=999"

do{
    try{
        $ADUseresult = Invoke-WebRequest -Headers $Headers -Uri $GraphLink -UseBasicParsing -Method "GET" -ContentType "application/json"
    }catch{
        Write-Host ''
        Write-Host ''
        Write-Host "Operation aborted. Please make sure that tenant has an Azure Active Directory Premium license, and you have the right permissions." -ForegroundColor red -BackgroundColor Black
        Write-Host ''
        Write-Host "Script completed successfully." -ForegroundColor Green -BackgroundColor Black
        Write-Host ''
        exit
    }
    $ADUseresult = $ADUseresult.Content | ConvertFrom-Json
        if ($ADUseresult.value) {
            $AADUsers += $ADUseresult.value
        }
        else {
            $AADUsers += $ADUseresult
        }
        $GraphLink = ($ADUseresult).'@odata.nextlink'
  } until (!($GraphLink)) 

$ADUserep =@()
foreach($ADUser in $AADUsers){
    $ADUserepobj = New-Object PSObject
    $ADUserepobj | Add-Member NoteProperty -Name "Object ID" -Value $ADUser.id
    $ADUserepobj | Add-Member NoteProperty -Name "Display Name" -Value $ADUser.displayName
    $ADUserepobj | Add-Member NoteProperty -Name "User Principal Name" -Value $ADUser.userPrincipalName
    if ($ADUser.accountEnabled){$ADUserepobj | Add-Member NoteProperty -Name "Account Enabled" -Value $ADUser.accountEnabled}else{$ADUserepobj | Add-Member NoteProperty -Name "Account Enabled" -Value "False"}
    if ($ADUser.onPremisesSyncEnabled){$ADUserepobj | Add-Member NoteProperty -Name "onPremisesSyncEnabled" -Value $ADUser.onPremisesSyncEnabled}else{$ADUserepobj | Add-Member NoteProperty -Name "onPremisesSyncEnabled" -Value "False"}
    $ADUserepobj | Add-Member NoteProperty -Name "Created DateTime (UTC)" -Value $ADUser.createdDateTime
    if (($ADUser.signInActivity).lastSignInDateTime) {$ADUserepobj | Add-Member NoteProperty -Name "Last Success Signin (UTC)" -Value ($ADUser.signInActivity).lastSignInDateTime}else{$ADUserepobj | Add-Member NoteProperty -Name "Last Success Signin (UTC)" -Value "N/A"}
    $ADUserep += $ADUserepobj
}

$Date=("{0:s}" -f (get-date)).Split("T")[0] -replace "-", ""
$Time=("{0:s}" -f (get-date)).Split("T")[1] -replace ":", ""
$filerep = "AzureADUsersLastLogin_" + $Date + $Time + ".csv"
try{
    $ADUserep | Export-Csv -path $filerep -NoTypeInformation
}catch{
    Write-Host ''
    Write-Host ''
    Write-Host "Operation aborted. Please make sure you have write permission on to write CSV file." -ForegroundColor red -BackgroundColor Black
    Write-Host ''
    Write-Host "Script completed successfully." -ForegroundColor Green -BackgroundColor Black
    Write-Host ''
    exit
}

''
Write-Host "==================================="
Write-Host "|Retreived Azure AD Users Summary:|"
Write-Host "==================================="
Write-Host "Number of retreived AAD Users:" $ADUserep.Count
''
$loc=Get-Location
Write-host $filerep "report has been created under the path:" $loc -ForegroundColor green

''
''
Write-Host "Script completed successfully." -ForegroundColor Green -BackgroundColor Black
''


PowerShell console output:
Alt text

CSV output:
Alt text



Azure AD User's Manager Report


  • Install-Module AzureAD
  • Connect to Azure AD using
$AzureAdCred = Get-Credential
Connect-AzureAD -Credential $AzureAdCred

Run following script from your PowerShell:
Connect-AzureAD -Credential $AzureAdCred
$output = @()
$users = Get-AzureADUser -All $true

foreach ($user in $users) {
    $manager = Get-AzureADUserManager -ObjectId $user.ObjectId
    $data = New-Object -TypeName psobject
    $data | Add-Member -MemberType NoteProperty -Name Name -Value $user.GivenName
    $data | Add-Member -MemberType NoteProperty -Name Surname -Value $user.Surname
	$data | Add-Member -MemberType NoteProperty -Name Mail -Value $user.Mail
    $data | Add-Member -MemberType NoteProperty -Name JobTitle -Value $user.JobTitle
    $data | Add-Member -MemberType NoteProperty -Name Manager -Value $manager.DisplayName 

    $output += $data
}

$output | Export-Csv -Path aad+manager.csv -NoTypeInformation
Note: Script is from https://techcommunity.microsoft.com/t5/sharepoint-developer/powershell-command-to-export-user-s-manager-name/m-p/1020360. 


Another method https://www.alitajran.com/export-azure-ad-users-to-csv-powershell/ is using MS Graph , and it might need admin grant permission. 




Azure Policy Report Using Powershell


Refer here to know more about Azure Policy.
Note: https://arindamhazra.com/script-to-report-azure-policy-details/
$currentDir = $(Get-Location).Path
$oDFile = "$($currentDir)\Policy_Definitions_Assignment.csv"

if(Test-Path $oDFile){Remove-Item $oDFile -Force}
"display Name,policy Type,mode,description,Policy Assignments,Assignment Count" | Out-File $oDFile -append -encoding ASCII
Get-AzPolicyDefinition | ForEach-Object{
	$displayName = $policyType = $mode = $description = $allAssignment = ""
	$assignmentCount = 0
	$displayName = $_.Properties.displayName
	$policyType = $_.Properties.policyType
	$mode = $_.Properties.mode
	$description = $_.Properties.description.replace(","," ")
	$polResId = $_.ResourceId
	Get-AzPolicyAssignment -PolicyDefinitionId $polResId | ForEach-Object{
		$allAssignment = $allAssignment + $_.Properties.displayName + ";"		
	}
	$allAssignment = $allAssignment.TrimEnd(";")
	if(!([string]::IsNullOrEmpty($allAssignment))){
		$assignmentCount = $allAssignment.split(";").count
	}	
"$displayName,$policyType,$mode,$description,$allAssignment,$assignmentCount" | Out-File $oDFile -append -encoding ASCII
}




Azure Policy - Resource Compliance Report Export Using Graph Exporler


Note: https://learn.microsoft.com/en-us/azure/governance/policy/samples/resource-graph-samples?tabs=azure-cli

List all non-compliant resources

Provides a list of all resources types that are in a NonCompliant state.


PolicyResources | where type == 'microsoft.policyinsights/policystates' | where properties.complianceState == 'NonCompliant' | extend NonCompliantResourceId = properties.resourceId, PolicyAssignmentName = properties.policyAssignmentName
    Modified version for all resources:
    PolicyResources
    | where type == 'microsoft.policyinsights/policystates'
    | extend NonCompliantResourceId = properties.resourceId, PolicyAssignmentName = properties.policyAssignmentName, PolicyDefinition = properties.policyDefinitionReferenceId, ResourceType = properties.resourceType, ResourceGroup = properties.resourceGroup, ResourceLocation = properties.resourceLocation
    




    References

    • https://github.com/12Knocksinna/Office365itpros



    No comments:

    Post a Comment