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
291 lines
9.2 KiB
PowerShell
291 lines
9.2 KiB
PowerShell
########################################################
|
|
#
|
|
# Common module functions
|
|
#
|
|
########################################################
|
|
function Add-ModuleMenuItems
|
|
{
|
|
Add-MenuItem (New-Object PSObject -Property @{
|
|
Title = (Get-ConditionalAccessName)
|
|
MenuID = "IntuneGraphAPI"
|
|
Script = [ScriptBlock]{Get-ConditionalAccess}
|
|
})
|
|
}
|
|
|
|
function Get-SupportedImportObjects
|
|
{
|
|
$global:importObjects += (New-Object PSObject -Property @{
|
|
Selected = $true
|
|
Title = (Get-ConditionalAccessName)
|
|
Script = [ScriptBlock]{
|
|
param($rootFolder)
|
|
|
|
Write-Status "Import all conditional access policies"
|
|
Import-AllConditionalAccessObjects (Join-Path $rootFolder (Get-ConditionalAccessFolderName))
|
|
}
|
|
})
|
|
}
|
|
|
|
function Get-SupportedExportObjects
|
|
{
|
|
$global:exportObjects += (New-Object PSObject -Property @{
|
|
Selected = $true
|
|
Title = (Get-ConditionalAccessName)
|
|
Script = [ScriptBlock]{
|
|
param($rootFolder)
|
|
|
|
Write-Status "Export all conditional access policies"
|
|
Get-ConditionalAccessObjects | ForEach-Object { Export-SingleConditionalAccess $PSItem.Object (Join-Path $rootFolder (Get-ConditionalAccessFolderName)) }
|
|
}
|
|
})
|
|
}
|
|
|
|
function Export-AllObjects
|
|
{
|
|
param($addObjectSubfolder)
|
|
|
|
$subFolder = ""
|
|
if($addObjectSubfolder) { $subFolder = Get-ConditionalAccessFolderName }
|
|
}
|
|
|
|
########################################################
|
|
#
|
|
# Object specific functions
|
|
#
|
|
########################################################
|
|
function Get-ConditionalAccessName
|
|
{
|
|
return "Conditional Access"
|
|
}
|
|
|
|
function Get-ConditionalAccessFolderName
|
|
{
|
|
return "ConditionalAccess"
|
|
}
|
|
|
|
function Get-ConditionalAccess
|
|
{
|
|
Write-Status "Loading conditional access objects"
|
|
$dgObjects.ItemsSource = @(Get-ConditionalAccessObjects)
|
|
|
|
#Scriptblocks that will perform the export tasks. empty by default
|
|
$script:exportParams = @{}
|
|
$script:exportParams.Add("ExportAllScript", [ScriptBlock]{
|
|
Export-AllConditionalAccess $global:txtExportPath.Text
|
|
Set-ObjectGrid
|
|
Write-Status ""
|
|
})
|
|
|
|
$script:exportParams.Add("ExportSelectedScript", [ScriptBlock]{
|
|
Export-SelectedConditionalAccess $global:txtExportPath.Text
|
|
Set-ObjectGrid
|
|
Write-Status ""
|
|
})
|
|
#Scriptblock that will perform the import all files
|
|
$script:importAll = [ScriptBlock]{
|
|
Import-AllConditionalAccessObjects $global:txtImportPath.Text
|
|
Set-ObjectGrid
|
|
}
|
|
|
|
#Scriptblock that will perform the import of selected files
|
|
$script:importSelected = [ScriptBlock]{
|
|
Import-ConditionalAccessObjects $global:lstFiles.ItemsSource -Selected
|
|
Set-ObjectGrid
|
|
}
|
|
|
|
#Scriptblock that will read json files
|
|
$script:getImportFiles = [ScriptBlock]{
|
|
Show-FileListBox
|
|
$global:lstFiles.ItemsSource = @(Get-JsonFileObjects $global:txtImportPath.Text -Exclude "*_Settings.json")
|
|
}
|
|
|
|
Add-DefaultObjectButtons -export ([scriptblock]{Show-DefaultExportGrid @script:exportParams}) -import ([scriptblock]{Show-DefaultImportGrid -ImportAll $script:importAll -ImportSelected $script:importSelected -GetFiles $script:getImportFiles}) -ViewFullObject ([scriptblock]{Get-ConditionalAccessObject $global:dgObjects.SelectedItem.Object})
|
|
}
|
|
|
|
function Get-ConditionalAccessObjects
|
|
{
|
|
#https://main.iam.ad.ext.azure.com/api/Policies/Policies?top=10&nextLink=null&appId=&includeBaseline=true
|
|
Get-AzureNativeObjects "Policies/Policies?top=10&appId=&includeBaseline=true" -property @('policyName') -allowPaging
|
|
}
|
|
|
|
function Get-ConditionalAccessObject
|
|
{
|
|
param($object, $additional = "")
|
|
|
|
if(-not $Object.policyId) { return }
|
|
|
|
if($Object.baselineType -eq 0)
|
|
{
|
|
Invoke-AzureNativeRequest "Policies/$($Object.policyId)$additional"
|
|
}
|
|
else
|
|
{
|
|
Invoke-AzureNativeRequest "BaselinePolicies/$($Object.policyId)$additional"
|
|
}
|
|
}
|
|
|
|
function Export-AllConditionalAccess
|
|
{
|
|
param($path = "$env:Temp")
|
|
|
|
if(-not (Test-Path $path)) { mkdir -Path $path -Force -ErrorAction SilentlyContinue | Out-Null }
|
|
|
|
if(Test-Path $path)
|
|
{
|
|
foreach($objTmp in ($global:dgObjects.ItemsSource))
|
|
{
|
|
Export-SingleConditionalAccess $objTmp.Object $path
|
|
}
|
|
}
|
|
}
|
|
|
|
function Export-SelectedConditionalAccess
|
|
{
|
|
param($path = "$env:Temp")
|
|
|
|
Export-SingleConditionalAccess $global:dgObjects.SelectedItem.Object $path
|
|
}
|
|
|
|
function Export-SingleConditionalAccess
|
|
{
|
|
param($psObj, $path = "$env:Temp")
|
|
|
|
if(-not $psObj) { return }
|
|
|
|
if($global:runningBulkExport -ne $true)
|
|
{
|
|
if($global:chkAddCompanyName.IsChecked) { $path = Join-Path $path $global:organization.displayName }
|
|
if($global:chkAddObjectType.IsChecked) { $path = Join-Path $path (Get-ConditionalAccessFolderName) }
|
|
}
|
|
|
|
if(-not (Test-Path $path)) { mkdir -Path $path -Force -ErrorAction SilentlyContinue | Out-Null }
|
|
|
|
if(Test-Path $path)
|
|
{
|
|
Write-Status "Export $($psObj.policyName)"
|
|
|
|
if($psObj.baselineType -eq 0)
|
|
{
|
|
$obj = Invoke-AzureNativeRequest "Policies/$($psObj.policyId)"
|
|
}
|
|
else
|
|
{
|
|
$obj = Invoke-AzureNativeRequest "BaselinePolicies/$($psObj.policyId)"
|
|
}
|
|
|
|
if($obj)
|
|
{
|
|
$fileName = "$path\$((Remove-InvalidFileNameChars $psObj.policyName)).json"
|
|
ConvertTo-Json $obj -Depth 5 | Out-File $fileName -Force
|
|
}
|
|
|
|
if($jsonObj.usersV2.included.groupIds)
|
|
{
|
|
$jsonObj.usersV2.included.groupIds | ForEach-Object { Add-GroupMigrationObject $PSItem }
|
|
}
|
|
|
|
if($jsonObj.usersV2.excluded.groupIds)
|
|
{
|
|
$jsonObj.usersV2.excluded.groupIds | ForEach-Object { Add-GroupMigrationObject $PSItem }
|
|
}
|
|
|
|
if($jsonObj.usersV2.included.userIds -or $jsonObj.usersV2.excluded.userIds)
|
|
{
|
|
Write-Log "Users are specified in $($psObj.policyName). User are not supported in this version. This conditional access policy might not be imported" 2
|
|
}
|
|
|
|
if($jsonObj.usersV2.included.roleIds -or $jsonObj.usersV2.excluded.roleIds)
|
|
{
|
|
Write-Log "Roles are specified in $($psObj.policyName). Roles are not supported in this version. This conditional access policy might not be imported" 2
|
|
}
|
|
|
|
if($jsonObj.conditions.namedNetworks.includedNetworkIds -or $jsonObj.conditions.namedNetworks.excludedNetworkIds)
|
|
{
|
|
Write-Log "Networks are specified in $($psObj.policyName). Named networks are not supported in this version. This conditional access policy might not be imported" 2
|
|
}
|
|
|
|
# There might be a lot more to check here...
|
|
|
|
$global:exportedObjects++
|
|
}
|
|
}
|
|
|
|
function Import-ConditionalAccess
|
|
{
|
|
param($obj)
|
|
|
|
Start-PreImport $obj
|
|
|
|
$json = Update-JsonForEnvironment $json
|
|
|
|
if($obj.baselineType -eq 0)
|
|
{
|
|
$obj.policyId = ""
|
|
$obj.isAllProtocolsEnabled = $true
|
|
$json = ConvertTo-Json $obj -Depth 10
|
|
$json = Update-JsonForEnvironment $json
|
|
|
|
if((Invoke-AzureNativeRequest "Policies/Validate" -Method POST -Body $json) -eq 11)
|
|
{
|
|
Invoke-AzureNativeRequest "Policies" -Method POST -Body $json | Out-Null
|
|
}
|
|
else
|
|
{
|
|
Write-Log "Policy validation of json data failed" 3
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Write-Log "Conditional Access Baseline Policies does not support import"
|
|
#Invoke-AzureNativeRequest "BaselinePolicies/$($obj.id)" -Method PUT -Body (ConvertTo-Json $obj -Depth 5) | Out-Null
|
|
}
|
|
}
|
|
|
|
function Import-AllConditionalAccessObjects
|
|
{
|
|
param($path = "$env:Temp")
|
|
|
|
Import-ConditionalAccessObjects (Get-JsonFileObjects $path)
|
|
}
|
|
|
|
function Import-ConditionalAccessObjects
|
|
{
|
|
param(
|
|
$Objects,
|
|
|
|
[switch]
|
|
$Selected
|
|
)
|
|
|
|
Write-Status "Import conditional access policies"
|
|
|
|
foreach($obj in $objects)
|
|
{
|
|
if($Selected -and $obj.Selected -ne $true) { continue }
|
|
|
|
Write-Log "Import Conditional Access: $($obj.Object.policyName)"
|
|
|
|
$response = Import-ConditionalAccess $obj.Object
|
|
|
|
if($response)
|
|
{
|
|
$global:importedObjects++
|
|
}
|
|
# No additionl assignments on conditional access policies
|
|
}
|
|
$dgObjects.ItemsSource = @(Get-ConditionalAccessObjects)
|
|
Write-Status ""
|
|
}
|
|
|
|
<#
|
|
# Get all networks
|
|
Get-AzureNativeObjects "NamedNetworksV2"
|
|
|
|
# Network example
|
|
#{"networkName":"Australia","cidrIpRanges":[],"categories":[],"applyToUnknownCountry":false,"countryIsoCodes":["AU"],"isTrustedLocation":false,"namedLocationsType":2}
|
|
|
|
Get-AzureNativeObjects "NamedNetworksV2" -Method POST -Body $json | Out-Nul
|
|
|
|
# Get all contry codes
|
|
NamedNetworksV2/CountryCodes
|
|
#> |