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.

Related posts:

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

Install Azure Module

Install-Module AzureAD
Install-module AzureADPreview

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
InstallModule msonline

Run the following cmdlet to connect to a Microsoft Service Portal:


$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.

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.
    Get-AzureADUsersLastSignIn PowerShell script.
    Get-AzureADUsersLastSignIn.ps1 is a PowerShell script retrieves Azure AD users with their last sign in date.
    Mohammad Zmaili
      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 {
        $ClientID = '1950a258-227b-4e31-a9cf-717495945fc2',
        $TenantID = 'common',
        $Resource = "",
        # Timeout in seconds to wait for user to complete sign in process
        $Timeout = 300
try {
    $DeviceCodeRequestParams = @{
        Method = 'POST'
        Uri    = "$TenantID/oauth2/devicecode"
        Body   = @{
            resource  = $Resource
            client_id = $ClientId
            redirect_uri = ""
            #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 = "" }
    $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    = "$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") {
        Start-Sleep -Seconds 1
    Write-Output $TokenRequest.access_token
finally {
    try {
        Remove-Item -Path $TempPage.FullName -Force -ErrorAction 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 = "$"
$GraphLink = $GraphLink + "select=id,userPrincipalName,displayName,accountEnabled,onPremisesSyncEnabled,createdDateTime,signInActivity&`$top=999"

        $ADUseresult = Invoke-WebRequest -Headers $Headers -Uri $GraphLink -UseBasicParsing -Method "GET" -ContentType "application/json"
        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 ''
    $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 $
    $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"
    $ADUserep | Export-Csv -path $filerep -NoTypeInformation
    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 ''

Write-Host "==================================="
Write-Host "|Retreived Azure AD Users Summary:|"
Write-Host "==================================="
Write-Host "Number of retreived AAD Users:" $ADUserep.Count
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



By netsec

Leave a Reply

Ads Blocker Image Powered by Code Help Pro

Ads Blocker Detected!!!

We have detected that you are using extensions to block ads. Please support us by disabling these ads blocker.

%d bloggers like this: