Files
macOS_IntuneManagement/Extensions/AzureNative.psm1
Micke b4c737dd6d Removed support for AzureRM
Az module is required for Native Azure objects (Conditional access, Azure branding and MDM/MAM settings)
Fixed limit on Conditional Access objects
Remove properties before import (date etc.)
Added WIP policies
Added support for installing Intune module for user only
2021-02-03 12:50:22 +11:00

221 lines
6.5 KiB
PowerShell

#Requires -module Az.Accounts
function Invoke-InitializeModule
{
if(-not $global:AzToken)
{
# Only allow re-logging if it failed the first time
$global:AuthenticatedToAzure = $false
}
#!!! - Used for testing login
#Disconnect-AzAccount -Username admin@delematelab2.onmicrosoft.com
}
function Connect-AzureNative
{
<#
.SYNOPSIS
Tries to connect to Azure with existing token
Uses Connect-AZAccount if no token found in cache
#>
param($user)
Write-Log "Authenticate to Azure (Az module). Try from cache with user $user"
$Context = (Get-AzContext -ListAvailable | Where { $_.Account.Id -eq $user } | select -first 1)
if (-not $Context)
{
$user | Clip # Copy login id to clipboard
# Run Connect-AZAccount in a separate runspace or it will hang
$Runspace = [runspacefactory]::CreateRunspace()
$PowerShell = [powershell]::Create()
$PowerShell.Runspace = $Runspace
$Runspace.Open()
$PowerShell.AddScript({Connect-AZAccount})
$PowerShell.Invoke()
[System.Windows.Forms.Application]::DoEvents()
$Context = (Get-AzContext -ListAvailable | Where { $_.Account.Id -eq $user } | select -first 1)
}
$global:AzToken = ""
try
{
$Resource = '74658136-14ec-4630-ad9b-26e160ff0fc6'
$global:AzToken = [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.AuthenticationFactory.Authenticate($context.Account, $context.Environment, $context.Tenant.Id, $null, "Never", $null, $Resource)
}
catch
{
Write-LogError "Failed to authenticate with Instance.AuthenticationFactory.Authenticate" $_.Exception
}
if(-not $global:AzToken)
{
Write-Log "Failed to authenticate" 3
}
else
{
Write-Log "Authenticated as $($global:AzToken.UserId)"
}
$global:AuthenticatedToAzure = $true
Set-MainTitle
}
# Invoke-AzureNativeRequest is based on the following project
# https://github.com/JustinGrote/Az.PortalAPI/tree/master/Az.PortalAPI
#
# Some small changes:
# - Get-AzContext is based on the same user as Intune user
# - Renamed Invoke-Request to Invoke-AzureNativeRequest
# - Added support for HTTP Method PATCH
# - Added support for paging with nextLink (Lazy solution...not fully tested but looks like it is working)
# - Removed Token parameter. Created the Connect-AzureNative to get token
# - Removed Context parameter
function Invoke-AzureNativeRequest {
<#
.SYNOPSIS
Runs a command against the Azure Portal API
#>
[CmdletBinding(SupportsShouldProcess)]
param (
#The target of your request. This is appended to the Portal API URI. Example: Permissions
[Parameter(Mandatory)]$Target,
#The command you wish to execute. Example: GetUserSystemRoleTemplateIds
[Parameter()]$Action,
#The body of your request. This is usually in JSON format
$Body,
#Specify the HTTP Method you wish to use. Defaults to GET
[ValidateSet("GET","POST","OPTIONS","DELETE","PATCH")]
$Method = "GET",
#The base URI for the Portal API. Typically you don't need to change this
[Uri]$baseURI = 'https://main.iam.ad.ext.azure.com/api/',
[URI]$requestOrigin = 'https://iam.hosting.portal.azure.net',
#The request ID for the session. You can generate one with [guid]::NewGuid().guid.
#Typically you only specify this if you're trying to retry an operation and don't want to duplicate the request, such as for a POST operation
$requestID = [guid]::NewGuid().guid,
[switch]$allowPaging
)
if(-not $global:AzToken -and $global:AuthenticatedToAzure -eq $false)
{
Connect-AzureNative $global:me.userPrincipalName
}
if(-not $global:AzToken)
{
return
}
#Combine the BaseURI and Target
[String]$ApiAction = $Target.TrimStart('/')
if ($Action) {
$ApiAction = $ApiAction + '/' + $Action
}
$uriStr = "$baseURI$ApiAction"
if($allowPaging)
{
$uri = [Uri]::New("$uriStr&nextLink=null")
}
else
{
$uri = [Uri]::New($baseURI,$ApiAction)
}
if(-not $global:AzToken.AccessToken.tostring())
{
Write-Log "No access token available" 3
return
}
$InvokeRestMethodParams = @{
Uri = $uri
Method = $Method
Header = [ordered]@{
Authorization = 'Bearer ' + $global:AzToken.AccessToken.tostring()
'Content-Type' = 'application/json'
'x-ms-client-request-id' = $requestID
'Host' = $baseURI.Host
'Origin' = 'https://iam.hosting.portal.azure.net'
}
Body = $Body
}
$max = 100
$cur = 0
$retObj = Invoke-RestMethod @InvokeRestMethodParams
if(($retObj | GM -MemberType NoteProperty -Name "nextLink"))
{
while($retObj.nextLink)
{
# Get more objects
$InvokeRestMethodParams["Uri"] = [Uri]::New($uriStr + "&nextLink=" + $retObj.nextLink)
$retObj = Invoke-RestMethod @InvokeRestMethodParams
if($cur -ge $max) { break }
$cur++ # Loop gets stuck if nextLink=null is added to the command line so make sure it doesn't hang forever
}
}
$retObj
}
function Get-AzureNativeObjects
{
param(
[Array]
$Target,
[Array]
$property,
[Array]
$exclude,
$SortProperty = "",
[switch]$allowPaging)
$objects = @()
$nativeObjects = Invoke-AzureNativeRequest $Target -allowPaging:($allowPaging -eq $true)
if(($nativeObjects | GM -Name "items"))
{
$objectList = $nativeObjects.Items
}
else
{
$objectList = $nativeObjects
}
foreach($nativeObject in $objectList)
{
$params = @{}
if($property) { $params.Add("Property", $property) }
if($exclude) { $params.Add("ExcludeProperty", $exclude) }
foreach($objTmp in ($nativeObject | select @params))
{
$objTmp | Add-Member -NotePropertyName "Object" -NotePropertyValue $nativeObject
$objects += $objTmp
}
}
if($objects.Count -gt 0 -and $SortProperty -and ($objects[0] | GM -MemberType NoteProperty -Name $SortProperty))
{
$objects = $objects | sort -Property $SortProperty
}
$objects
}