PowerShell cmdlet to get attributes not matching between two objects

This is a very quick cmdlet for getting attributes that does not match between two objects

<#
.Synopsis
   Returns a list of all attributes that does not match between two objects
#>
function Get-MismatchedAttributes
{
    [CmdletBinding()]
    [OutputType([boolean])]
    Param
    (
        [Parameter(Mandatory=$true,
                    ValueFromPipelineByPropertyName=$false,
                    Position=0)]
        $ReferenceObject,
              
        [Parameter(Mandatory=$true,
                    ValueFromPipelineByPropertyName=$false,
                    Position=1)]
        $DifferenceObject,

        [Parameter(Mandatory=$false,
                    ValueFromPipelineByPropertyName=$false,
                    Position=2)]
        [String[]] $Attributes = $null
    )

    if($Attributes -eq $null) {
        $Attributes = @(
            $ReferenceObject | gm -MemberType NoteProperty | select -exp Name
            $DifferenceObject | gm -MemberType NoteProperty | select -exp Name
        ) | Sort -Unique
    }
    
    $Attributes | Where {$ReferenceObject.$($_) -ne $DifferenceObject.$($_)}
}



$obj1 = [PSCustomObject] @{
    Attr1 = "abc"
    Attr2 = "def"
    Attr3 = "klm"
}

$obj2 = [PSCustomObject] @{
    Attr1 = "abc"
    Attr2 = "okj"
}

Write-Host "Attributes that does not match, limited to Attr1 and Attr2" -ForegroundColor Red
Get-MismatchedAttributes $obj1 $obj2 -Attributes "Attr1","Attr2"

Write-Host "All attributes that does not match" -ForegroundColor Red
Get-MismatchedAttributes $obj1 $obj2

Quick PowerShell cmdlet to get query parameters sent to localhost

When testing Azure AD applications or showing of things such as implicit flow, authorization code flow etc., it can be very useful to have a listener going on localhost in order to provide the browser a valid redirect url. The following cmdlet can be used to do this, without the need to install anything.

function Get-HttpQueryParametersSentToLocalhost
{
    [CmdletBinding()]
    Param
    (
        [Parameter(Mandatory=$false,
                   ValueFromPipelineByPropertyName=$true,
                   Position=0)]
        [int] $Port = 8080,

        [Parameter(Mandatory=$false,
                   ValueFromPipelineByPropertyName=$true,
                   Position=1)]
        [string] $Response = "Done"
    )

    $listener = New-Object System.Net.HttpListener
    $listener.Prefixes.Add("http://localhost:$Port/")
    Write-verbose "Waiting for request at http://localhost:$Port/"
    $listener.Start()
    $context = $listener.GetContext()
    $Content = [System.Text.Encoding]::UTF8.GetBytes($Response)
    $Context.Response.OutputStream.Write($Content, 0, $Content.Length)
    $Context.Response.Close()
    $listener.Dispose()
    $Context.Request.RawUrl -split "[?&]" -like "*=*" | foreach -Begin {$h = @{}} -Process {$h[($_ -split "=",2 | select -index 0)] = ($_ -split "=",2 | select -index 1)} -End {$h}
    
}

$parameters = Get-HttpQueryParametersSentToLocalhost -Verbose -Port 8080
$parameters | Out-GridView

How, try to do to http://localhost:8080/asd/?test=a&idtoken=asdd&code=123 and check out what happens in PowerShell. 🙂

Ill create a new blog post that uses this to demonstrate different OpenID Connect flows later.

Building a multi tenant Azure AD application with roles

Through this blog post I will show how to build a multi tenant Azure AD application, where your customers can control role assignments through regular Azure AD app roles that they again can manage through Azure AD Entitlement Management, Access Reviews and dynamically assigned through dynamic groups.

The point of doing this kind of implementation is that you can externalize role management to the customer’s Azure AD, so that the customer can use all the great Azure AD features that exist for governing access, rather than needing to have yet another interface (your application) for assigning roles.

Continue reading “Building a multi tenant Azure AD application with roles”

PowerShell for verifying Norwegian social security number / personnummer

function Get-IsSSNValid
{
    [CmdletBinding()]
    [Alias()]
    Param
    (
        # Param1 help description
        [Parameter(Mandatory=$true,
                   ValueFromPipeline=$true,
                   Position=0)]
        [String] $SSN
    )
 
  
 
    Process
    {
        $FirstPart = $SSN.Substring(0,9)
        $Check = $SSN.Substring(9,2)
 
  
 
        $k1 = 11 - ((3 * [int]::Parse($FirstPart.Chars(0)) + 7 * [int]::Parse($FirstPart.Chars(1)) + 6 * [int]::Parse($FirstPart.Chars(2)) + 1 * [int]::Parse($FirstPart.Chars(3)) + 8 * [int]::Parse($FirstPart.Chars(4)) + 9 * [int]::Parse($FirstPart.Chars(5)) + 4 * [int]::Parse($FirstPart.Chars(6)) + 5 * [int]::Parse($FirstPart.Chars(7)) + 2 * [int]::Parse($FirstPart.Chars(8))) % 11)
        if($k1 -eq "11") {
            $k1 = 0
        }

        $k2 = 11 - ((5 * [int]::Parse($FirstPart.Chars(0)) + 4 * [int]::Parse($FirstPart.Chars(1)) + 3 * [int]::Parse($FirstPart.Chars(2)) + 2 * [int]::Parse($FirstPart.Chars(3)) + 7 * [int]::Parse($FirstPart.Chars(4)) + 6 * [int]::Parse($FirstPart.Chars(5)) + 5 * [int]::Parse($FirstPart.Chars(6)) + 4 * [int]::Parse($FirstPart.Chars(7)) + 3 * [int]::Parse($FirstPart.Chars(8)) + 2 * $k1) % 11)
        if($k2 -eq "11") {
            $k2 = 0
        }
        return [int]::Parse($Check.Chars(0)) -eq $k1 -and [int]::Parse($Check.Chars(1)) -eq $k2
    }
}
 
  
 
Get-IsSSNValid "12345678910"

Sending merged emails through the Microsoft Graph using PowerShell

Some times there is a need to send merged emails to users or customers, where certain placeholders are replaced by usernames, email addresses, names etc. This blog post contains a script that can do this for you, using the Microsoft Graph. You need a regular account with Office 365 and Exchange Online for this to work.

Continue reading “Sending merged emails through the Microsoft Graph using PowerShell”