Version 3 Beta 1 - Complete re-write

This commit is contained in:
Micke
2021-04-13 17:57:12 +10:00
parent 2dfaf1bfba
commit c7f8cbe760
90 changed files with 28774 additions and 7724 deletions

View File

@@ -1,332 +0,0 @@
########################################################
#
# Common module functions
#
########################################################
function Add-ModuleMenuItems
{
Add-MenuItem (New-Object PSObject -Property @{
Title = (Get-AppProtectionName)
MenuID = "IntuneGraphAPI"
Script = [ScriptBlock]{Get-AppProtections}
})
}
function Get-SupportedImportObjects
{
$global:importObjects += (New-Object PSObject -Property @{
Selected = $true
Title = (Get-AppProtectionName)
Script = [ScriptBlock]{
param($rootFolder)
Write-Status "Import all app protection/configuration policies"
Import-AllAppProtectionObjects (Join-Path $rootFolder (Get-AppProtectionFolderName))
}
})
}
function Get-SupportedExportObjects
{
$global:exportObjects += (New-Object PSObject -Property @{
Selected = $true
Title = (Get-AppProtectionName)
Script = [ScriptBlock]{
param($rootFolder)
Write-Status "Export all app protection/configuration policies"
Get-AppProtectionObjects | ForEach-Object { Export-SingleAppProtection $PSItem.Object (Join-Path $rootFolder (Get-AppProtectionFolderName)) }
}
})
}
function Export-AllObjects
{
param($addObjectSubfolder)
$subFolder = ""
if($addObjectSubfolder) { $subFolder = Get-AppProtectionFolderName }
}
########################################################
#
# Object specific functions
#
########################################################
function Get-AppProtectionName
{
return "App Protection/Configuration"
}
function Get-AppProtectionFolderName
{
return "AppProtection"
}
function Get-AppProtections
{
Write-Status "Loading app protections and configurations"
$dgObjects.ItemsSource = @(Get-AppProtectionObjects)
#Scriptblocks that will perform the export tasks. empty by default
$script:exportParams = @{}
$script:exportParams.Add("ExportAllScript", [ScriptBlock]{
Export-AllAppProtections $global:txtExportPath.Text
Set-ObjectGrid
Write-Status ""
})
$script:exportParams.Add("ExportSelectedScript", [ScriptBlock]{
Export-SelectedAppProtection $global:txtExportPath.Text
Set-ObjectGrid
Write-Status ""
})
#Scriptblock that will perform the import all files
$script:importAll = [ScriptBlock]{
Import-AllAppProtectionObjects $global:txtImportPath.Text
Set-ObjectGrid
}
#Scriptblock that will perform the import of selected files
$script:importSelected = [ScriptBlock]{
Import-AppProtectionObjects $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}) -copy ([scriptblock]{Copy-AppProtection}) -ViewFullObject ([scriptblock]{Get-AppProtectionObject $global:dgObjects.SelectedItem.Object}) -ForceFullObject
}
function Get-AppProtectionObjects
{
Get-GraphObjects -Url "/deviceAppManagement/managedAppPolicies"
}
function Get-AppProtectionObject
{
param($object, $additional = "")
if(-not $object.id) { return }
$objType = Get-AppProtectionObjectType $object."@odata.type"
$expand = ""
if($objType -eq "targetedManagedAppConfigurations")
{
$expand = "?`$expand=Apps"
}
if($objType)
{
Invoke-GraphRequest -Url "/deviceAppManagement/$objType/$($object.id)$($expand)"
}
}
function Export-AllAppProtections
{
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-SingleAppProtection $objTmp.Object $path
}
}
}
function Export-SelectedAppProtection
{
param($path = "$env:Temp")
Export-SingleAppProtection $global:dgObjects.SelectedItem.Object $path
}
function Export-SingleAppProtection
{
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-AppProtectionFolderName) }
}
if(-not (Test-Path $path)) { mkdir -Path $path -Force -ErrorAction SilentlyContinue | Out-Null }
if(Test-Path $path)
{
Write-Status "Export $($psObj.displayName)"
$obj = Get-AppProtectionObjectForExport $psObj
if($obj)
{
$fileName = "$path\$((Remove-InvalidFileNameChars $obj.displayName)).json"
ConvertTo-Json $obj -Depth 5 | Out-File $fileName -Force
Add-MigrationInfo $obj.assignments
}
$global:exportedObjects++
}
}
function Get-AppProtectionObjectType
{
param($odataType)
if($odataType -like "*targetedManagedAppConfiguration*")
{
"targetedManagedAppConfigurations"
}
elseif($odataType -like "*iosManagedAppProtection*")
{
"iosManagedAppProtections"
}
elseif($odataType -like "*androidManagedAppProtection*")
{
"androidManagedAppProtections"
}
elseif($odataType -like "*mdmWindowsInformationProtectionPolicy*")
{
# Win 10 - With enrollment e.g. Intune enrolled Win 10 devices
"mdmWindowsInformationProtectionPolicies"
}
elseif($odataType -like "*windowsInformationProtectionPolicy*")
{
# Win 10 - Without enrollment e.g. MAM polices for Win 10
"WindowsInformationProtectionPolicies"
}
}
function Get-AppProtectionObjectForExport
{
param($obj)
$objType = Get-AppProtectionObjectType $obj."@odata.type"
$expand = "?`$expand=assignments"
if($objType -eq "targetedManagedAppConfigurations")
{
$expand += ",Apps"
}
if($objType)
{
Invoke-GraphRequest -Url "/deviceAppManagement/$objType/$($obj.id)$($expand)"
}
}
function Copy-AppProtection
{
if(-not $dgObjects.SelectedItem)
{
[System.Windows.MessageBox]::Show("No object selected`n`nSelect app protection/configuration item you want to copy", "Error", "OK", "Error")
return
}
$ret = Show-InputDialog "Copy app protection/configuration" "Select name for the new policy" "$($dgObjects.SelectedItem.displayName) - Copy"
if($ret)
{
# Export profile
Write-Status "Export $($dgObjects.SelectedItem.displayName)"
$obj = Get-AppProtectionObjectForExport $dgObjects.SelectedItem.Object
if($obj)
{
# Remove assignment properties
Remove-ObjectProperty $obj "assignments"
Remove-ObjectProperty $obj "assignments@odata.context"
# Import new profile
$obj.displayName = $ret
Import-AppProtection $obj | Out-Null
$dgObjects.ItemsSource = @(Get-AppProtectionObjects)
}
Write-Status ""
}
$dgObjects.Focus()
}
function Import-AppProtection
{
param($obj)
if(($obj | GM -MemberType NoteProperty -Name "Apps"))
{
$apps = $obj.Apps
}
Start-PreImport $obj -RemoveProperties @("apps","apps@odata.context")
Write-Status "Import $($obj.displayName)"
$objType = Get-AppProtectionObjectType $obj."@odata.context"
if($objType)
{
#Import the app configuration policy
$response = Invoke-GraphRequest -Url "/deviceAppManagement/$objType" -Content (ConvertTo-Json $obj -Depth 5) -HttpMethod POST
if($response -and $apps)
{
# Import targeted apps
$response2 = Invoke-GraphRequest -Url "/deviceAppManagement/$objType/$($response.Id)/targetApps" -Content "{ apps: $(ConvertTo-Json $apps -Depth 5)}" -HttpMethod POST
}
$response
}
}
function Import-AllAppProtectionObjects
{
param($path = "$env:Temp")
Import-AppProtectionObjects (Get-JsonFileObjects $path)
}
function Import-AppProtectionObjects
{
param(
$Objects,
[switch]
$Selected
)
Write-Status "Import app protection/configuration policies"
foreach($obj in $objects)
{
if($Selected -and $obj.Selected -ne $true) { continue }
Write-Log "Import App Protection/Configuration: $($obj.Object.displayName)"
$assignments = Get-GraphAssignmentsObject $obj.Object ($obj.FileInfo.DirectoryName + "\" + $obj.FileInfo.BaseName + "_assignments.json")
$response = Import-AppProtection $obj.Object
if($response)
{
$global:importedObjects++
$dataType = Get-AppProtectionObjectType $response."@odata.context"
if($dataType)
{
Import-GraphAssignments $assignments "assignments" "/deviceAppManagement/$dataType/$($response.Id)/assign"
}
}
}
$dgObjects.ItemsSource = @(Get-AppProtectionObjects)
Write-Status ""
}

View File

@@ -1,249 +0,0 @@
########################################################
#
# Common module functions
#
########################################################
function Add-ModuleMenuItems
{
Add-MenuItem (New-Object PSObject -Property @{
Title = (Get-AutoPilotName)
MenuID = "IntuneGraphAPI"
Script = [ScriptBlock]{Get-AutoPilots}
})
}
function Get-SupportedImportObjects
{
$global:importObjects += (New-Object PSObject -Property @{
Selected = $true
Title = (Get-AutoPilotName)
Script = [ScriptBlock]{
param($rootFolder)
Write-Status "Import all AutoPilot policies"
Import-AllAutoPilotObjects (Join-Path $rootFolder (Get-AutoPilotFolderName))
}
})
}
function Get-SupportedExportObjects
{
$global:exportObjects += (New-Object PSObject -Property @{
Selected = $true
Title = (Get-AutoPilotName)
Script = [ScriptBlock]{
param($rootFolder)
Write-Status "Export all AutoPilot policies"
Get-AutoPilotObjects | ForEach-Object { Export-SingleAutoPilotObject $PSItem.Object (Join-Path $rootFolder (Get-AutoPilotFolderName)) }
}
})
}
function Export-AllObjects
{
param($addObjectSubfolder)
$subFolder = ""
if($addObjectSubfolder) { $subFolder = Get-AutoPilotFolderName }
}
########################################################
#
# Object specific functions
#
########################################################
function Get-AutoPilotName
{
(Get-AutoPilotFolderName)
}
function Get-AutoPilotFolderName
{
"AutoPilot"
}
function Get-AutoPilots
{
Write-Status "Loading AutoPilot profiles"
$dgObjects.ItemsSource = @(Get-AutoPilotObjects)
#Scriptblocks that will perform the export tasks. empty by default
$script:exportParams = @{}
$script:exportParams.Add("ExportAllScript", [ScriptBlock]{
Export-AllAutoPilots $global:txtExportPath.Text
Set-ObjectGrid
Write-Status ""
})
$script:exportParams.Add("ExportSelectedScript", [ScriptBlock]{
Export-SelectedAutoPilotObject $global:txtExportPath.Text
Set-ObjectGrid
Write-Status ""
})
#Scriptblock that will perform the import all files
$script:importAll = [ScriptBlock]{
Import-AllAutoPilotObjects $global:txtImportPath.Text
Set-ObjectGrid
}
#Scriptblock that will perform the import of selected files
$script:importSelected = [ScriptBlock]{
Import-AutoPilotObjects $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}) -copy ([scriptblock]{Copy-AutoPilot}) -ViewFullObject ([scriptblock]{Get-AutoPilotObject $global:dgObjects.SelectedItem.Object})
}
function Get-AutoPilotObjects
{
Get-GraphObjects -Url "/deviceManagement/windowsAutopilotDeploymentProfiles"
}
function Get-AutoPilotObject
{
param($object, $additional = "")
if(-not $Object.id) { return }
Invoke-GraphRequest -Url "/deviceManagement/windowsAutopilotDeploymentProfiles/$($Object.id)$additional"
}
function Export-AllAutoPilots
{
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-SingleAutoPilotObject $objTmp.Object $path
}
}
}
function Export-SelectedAutoPilotObject
{
param($path = "$env:Temp")
Export-SingleAutoPilotObject $global:dgObjects.SelectedItem.Object $path
}
function Export-SingleAutoPilotObject
{
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-AutoPilotFolderName) }
}
if(-not (Test-Path $path)) { mkdir -Path $path -Force -ErrorAction SilentlyContinue | Out-Null }
if(Test-Path $path)
{
Write-Status "Export $($psObj.displayName)"
$obj = Invoke-GraphRequest -Url "/deviceManagement/windowsAutopilotDeploymentProfiles/$($psObj.id)?`$expand=assignments"
if($obj)
{
$fileName = "$path\$((Remove-InvalidFileNameChars $obj.displayName)).json"
ConvertTo-Json $obj -Depth 5 | Out-File $fileName -Force
Add-MigrationInfo $obj.assignments
}
$global:exportedObjects++
}
}
function Copy-AutoPilot
{
if(-not $dgObjects.SelectedItem)
{
[System.Windows.MessageBox]::Show("No object selected`n`nSelect AutoPilot item you want to copy", "Error", "OK", "Error")
return
}
$ret = Show-InputDialog "Copy AutoPilot" "Select name for the new object" "$($dgObjects.SelectedItem.displayName) Copy"
if($ret)
{
# Export profile
Write-Status "Export $($dgObjects.SelectedItem.displayName)"
# Convert to Json and back to clone the object
$obj = ConvertTo-Json $dgObjects.SelectedItem.Object -Depth 5 | ConvertFrom-Json
if($obj)
{
# Import new profile
$obj.displayName = Remove-InvalidFileNameChars $ret
Import-AutoPilot $obj | Out-Null
$dgObjects.ItemsSource = @(Get-AutoPilotObjects)
}
Write-Status ""
}
$dgObjects.Focus()
}
function Import-AutoPilot
{
param($obj)
Write-Status "Import $($obj.displayName)"
Start-PreImport $obj
Invoke-GraphRequest -Url "/deviceManagement/windowsAutopilotDeploymentProfiles" -Content (ConvertTo-Json $obj -Depth 5) -HttpMethod POST
}
function Import-AllAutoPilotObjects
{
param(
$path = "$env:Temp"
)
Import-AutoPilotObjects (Get-JsonFileObjects $path)
}
function Import-AutoPilotObjects
{
param(
$Objects,
[switch]
$Selected
)
Write-Status "Import AutoPilot profiles"
foreach($obj in $objects)
{
if($Selected -and $obj.Selected -ne $true) { continue }
Write-Log "Import AutoPilot profile: $($obj.Object.displayName)"
$assignments = Get-GraphAssignmentsObject $obj.Object ($obj.FileInfo.DirectoryName + "\" + $obj.FileInfo.BaseName + "_assignments.json")
$response = Import-AutoPilot $obj.Object
if($response)
{
$global:importedObjects++
Import-GraphAssignments2 $assignments "/deviceManagement/windowsAutopilotDeploymentProfiles/$($response.Id)/assignments"
}
}
$dgObjects.ItemsSource = @(Get-AutoPilotObjects)
Write-Status ""
}

View File

@@ -1,319 +0,0 @@
########################################################
#
# Common module functions
#
########################################################
function Add-ModuleMenuItems
{
Add-MenuItem (New-Object PSObject -Property @{
Title = (Get-AZBrandingName)
MenuID = "IntuneGraphAPI"
Script = [ScriptBlock]{Get-AZBrandings}
})
}
function Get-SupportedImportObjects
{
$global:importObjects += (New-Object PSObject -Property @{
Selected = $true
Title = (Get-AZBrandingName)
Script = [ScriptBlock]{
param($rootFolder)
Write-Status "Import all Azure branding"
Import-AllAZBrandingObjects (Join-Path $rootFolder (Get-AZBrandingFolderName))
}
})
}
function Get-SupportedExportObjects
{
$global:exportObjects += (New-Object PSObject -Property @{
Selected = $true
Title = (Get-AZBrandingName)
Script = [ScriptBlock]{
param($rootFolder)
Write-Status "Export all Azure branding"
Get-AZBrandingObjects | ForEach-Object { Export-SingleAZBranding $PSItem.Object (Join-Path $rootFolder (Get-AZBrandingFolderName)) }
}
})
}
function Export-AllObjects
{
param($addObjectSubfolder)
$subFolder = ""
if($addObjectSubfolder) { $subFolder = Get-AZBrandingFolderName }
}
########################################################
#
# Object specific functions
#
########################################################
function Get-AZBrandingName
{
return "Azure Branding"
}
function Get-AZBrandingFolderName
{
return "AZBranding"
}
function Get-AZBrandings
{
Write-Status "Loading Azure brandings"
$dgObjects.ItemsSource = @(Get-AZBrandingObjects)
#Scriptblocks that will perform the export tasks. empty by default
$script:exportParams = @{}
$script:exportParams.Add("ExportAllScript", [ScriptBlock]{
Export-AllAZBrandings $global:txtExportPath.Text
Set-ObjectGrid
Write-Status ""
})
$script:exportParams.Add("ExportSelectedScript", [ScriptBlock]{
Export-SelectedAZBranding $global:txtExportPath.Text
Set-ObjectGrid
Write-Status ""
})
$script:exportParams.Add("DisplayColumn", "localeDisplayName")
#Scriptblock that will perform the import all files
$script:importAll = [ScriptBlock]{
Import-AllAZBrandingObjects $global:txtImportPath.Text
Set-ObjectGrid
}
#Scriptblock that will perform the import of selected files
$script:importSelected = [ScriptBlock]{
Import-AZBrandingObjects $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-AZBrandingObject $global:dgObjects.SelectedItem.Object})
}
function Get-AZBrandingObjects
{
$response = Get-AzureNativeObjects "LoginTenantBrandings" -property @('locale', 'localeDisplayName')
if($response)
{
$response | Where { $_.Object.isConfigured -eq $true }
}
}
function Get-AZBrandingObject
{
param($object, $additional = "")
if(-not $Object.locale) { return }
Invoke-AzureNativeRequest "LoginTenantBrandings/$($Object.locale)$additional"
}
function Export-AllAZBrandings
{
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-SingleAZBranding $objTmp.Object $path
}
}
}
function Export-SelectedAZBranding
{
param($path = "$env:Temp")
Export-SingleAZBranding $global:dgObjects.SelectedItem.Object $path
}
function Export-SingleAZBranding
{
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-AZBrandingFolderName) }
}
if(-not (Test-Path $path)) { mkdir -Path $path -Force -ErrorAction SilentlyContinue | Out-Null }
if(Test-Path $path)
{
Write-Status "Export $($psObj.localeDisplayName)"
$obj = Invoke-AzureNativeRequest "LoginTenantBrandings/$($psObj.locale)"
if($obj)
{
$fileName = "$path\$((Remove-InvalidFileNameChars $obj.localeDisplayName)).json"
ConvertTo-Json $obj -Depth 5 | Out-File $fileName -Force
Save-AzureBrandingFile $obj "tileLogoUrl" $path
Save-AzureBrandingFile $obj "bannerLogoUrl" $path
Save-AzureBrandingFile $obj "illustrationUrl" $path
Save-AzureBrandingFile $obj "squareLogoDarkUrl" $path
$global:exportedObjects++
}
Set-ObjectPath $global:txtExportPath.Text
}
}
function Save-AzureBrandingFile
{
param($obj, $prop, $path)
if(-not $obj.$prop) { return }
$arr=$obj.$prop.Split('.')
if($arr.Length -ne 1)
{
return
}
$fileType = "jpg" # Assume...not OK. $arr[0] contains information about what kind of file it is
$fileName = "$path\$((Remove-InvalidFileNameChars "$($obj.localeDisplayName).$prop.$fileType"))"
try
{
if(Test-Path $fileName)
{
Remove-Item -Path $fileName -Force
}
[IO.File]::WriteAllBytes($fileName, [System.Convert]::FromBase64String($arr[1]))
}
catch {}
}
function Import-AZBranding
{
param($obj)
if($global:runningBulkImport -eq $true)
{
# Update Default and create the rest...
$createNew = $obj.locale -ne 0
}
else
{
$curObj = $global:lstFiles.ItemsSource | Where { $_.Object.locale -eq $obj.locale }
if($curObj -and $obj.locale -ne 0)
{
return # Do not update existing object except default
}
elseif(-not $curObj)
{
$createNew = $true
}
else
{
$createNew = $false
}
}
$json = "{"
if($createNew) { $json += "`"locale`":`"$($obj.locale)`"," }
if($obj.signInUserIdLabel) { $json += "`"userIdLabel`": `"$($obj.signInUserIdLabel)`"," }
if($obj.signInPageText) { $json += "`"boilerPlateText`": `"$($obj.signInPageText)`"," }
if($obj.signInBackColor) { $json += "`"backgroundColor`": `"$($obj.signInBackColor)`"," }
if($obj.tileLogoUrl) { $json += "`"tileLogoUrl`": `"$($obj.tileLogoUrl)`"," }
if($obj.bannerLogoUrl) { $json += "`"bannerLogoUrl`": `"$($obj.bannerLogoUrl)`"," }
if($obj.illustrationUrl) { $json += "`"illustrationUrl`": `"$($obj.illustrationUrl)`"," }
if($obj.squareLogoDarkUrl) { $json += "`"squareLogoDarkUrl`": `"$($obj.squareLogoDarkUrl)`"," }
if($obj.hideKeepMeSignedIn -and $obj.locale -eq 0) { $json += "`"keepMeSignedInDisabled`": $($obj.hideKeepMeSignedIn.ToString().ToLower())," }
if($createNew)
{
if($curObj.bannerLogoUrl -ne $curObj.bannerLogoUrl)
{
$json += "`"isTileLogoUpdated`":true,"
}
if($curObj.illustrationUrl -ne $curObj.illustrationUrl)
{
$json += "`"isIllustrationImageUpdated`":true,"
}
if($curObj.squareLogoDarkUrl -ne $curObj.squareLogoDarkUrl)
{
$json += "`"isSquareDarkLogoUpdated`":true,"
}
if($curObj.bannerLogoUrl -ne $curObj.bannerLogoUrl)
{
$json += "`"isBannerLogoUpdated`":true,"
}
}
$json = $json.TrimEnd(',')
$json += "}"
Write-Status "Import $($obj.localeDisplayName)"
if($createNew)
{
Invoke-AzureNativeRequest "LoginTenantBrandings" -Method POST -Body $json | Out-Null
}
else
{
Invoke-AzureNativeRequest "LoginTenantBrandings/$($obj.locale)" -Method PATCH -Body $json | Out-Null
}
}
function Import-AllAZBrandingObjects
{
param($path = "$env:Temp")
Import-AZBrandingObjects (Get-JsonFileObjects $path)
}
function Import-AZBrandingObjects
{
param(
$Objects,
[switch]
$Selected
)
Write-Status "Import Azure brandings"
foreach($obj in $objects)
{
if($Selected -and $obj.Selected -ne $true) { continue }
Write-Log "Import Azure branding"
$response = Import-AZBranding $obj.Object
if($response)
{
$global:importedObjects++
}
}
$dgObjects.ItemsSource = @(Get-AZBrandingObjects)
Write-Status ""
}

View File

@@ -1,221 +0,0 @@
#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
}

View File

@@ -1,306 +0,0 @@
########################################################
#
# Common module functions
#
########################################################
function Add-ModuleMenuItems
{
Add-MenuItem (New-Object PSObject -Property @{
Title = (Get-BaselineTemplatesName)
MenuID = "IntuneGraphAPI"
Script = [ScriptBlock]{Get-BaselineTemplates}
})
Add-MenuItem (New-Object PSObject -Property @{
Title = (Get-BaselineName)
MenuID = "IntuneGraphAPI"
Script = [ScriptBlock]{Get-BaselineProfiles}
})
}
function Get-SupportedImportObjects
{
$global:importObjects += (New-Object PSObject -Property @{
Selected = $true
Title = (Get-AppProtectionName)
Script = [ScriptBlock]{
param($rootFolder)
Write-Status "Import all baseline policies"
Import-AllBaselineProfileObjects (Join-Path $rootFolder (Get-BaselineFolderName))
}
})
}
function Get-SupportedExportObjects
{
$global:exportObjects += (New-Object PSObject -Property @{
Selected = $true
Title = (Get-AppProtectionName)
Folder = (Get-BaselineFolderName)
Script = [ScriptBlock]{
param($rootFolder)
Write-Status "Import all baseline policies"
Get-BaselineProfileObjects | ForEach-Object { Export-SingleBaselineProfile $PSItem.Object (Join-Path $rootFolder (Get-BaselineFolderName)) }
}
})
}
function Export-AllObjects
{
param($addObjectSubfolder)
$subFolder = ""
if($addObjectSubfolder) { $subFolder = Get-BaselineFolderName }
}
########################################################
#
# Object specific functions
#
########################################################
function Get-BaselineTemplatesName
{
return "Baseline Templates"
}
function Get-BaselineName
{
return "Baseline Profiles"
}
function Get-BaselineFolderName
{
return "Baseline"
}
function Get-BaselineTemplates
{
Write-Status "Loading baseline templates" -SkipLog
$dgObjects.ItemsSource = @(Get-BaselineTemplateObjects)
}
function Get-BaselineTemplateObjects
{
Get-GraphObjects -Url "/deviceManagement/templates"
}
function Get-BaselineProfiles
{
Write-Status "Loading banding profiles" -SkipLog
$dgObjects.ItemsSource = @(Get-BaselineProfileObjects)
#Scriptblocks that will perform the export tasks. empty by default
$script:exportParams = @{}
$script:exportParams.Add("ExportAllScript", [ScriptBlock]{
Export-AllBaselineProfiles $global:txtExportPath.Text
Set-ObjectGrid
Write-Status ""
})
$script:exportParams.Add("ExportSelectedScript", [ScriptBlock]{
Export-SelectedBaselineProfile $global:txtExportPath.Text
Set-ObjectGrid
Write-Status ""
})
#Scriptblock that will perform the import all files
$script:importAll = [ScriptBlock]{
Import-AllBaselineProfileObjects $global:txtImportPath.Text
Set-ObjectGrid
}
#Scriptblock that will perform the import of selected files
$script:importSelected = [ScriptBlock]{
Import-BaselineProfileObjects $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","*_assignments.json"))
}
Add-DefaultObjectButtons -export ([scriptblock]{Show-DefaultExportGrid @script:exportParams}) -import ([scriptblock]{Show-DefaultImportGrid -ImportAll $script:importAll -ImportSelected $script:importSelected -GetFiles $script:getImportFiles}) -copy ([scriptblock]{Copy-BaselineProfile}) -ViewFullObject ([scriptblock]{Get-BaselineProfileObject $global:dgObjects.SelectedItem.Object})
}
function Get-BaselineProfileObjects
{
Get-GraphObjects -Url "/deviceManagement/intents"
}
function Get-BaselineProfileObject
{
param($object, $additional = "")
if(-not $Object.id) { return }
$profile = Invoke-GraphRequest -Url "/deviceManagement/intents/$($Object.id)"
$settings = Invoke-GraphRequest -Url "/deviceManagement/intents/$($Object.id)/Settings"
@($profile, $settings)
}
function Export-AllBaselineProfiles
{
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-SingleBaselineProfile $objTmp.Object $path
}
}
}
function Export-SelectedBaselineProfile
{
param($path = "$env:Temp")
Export-SingleBaselineProfile $global:dgObjects.SelectedItem.Object $path
}
function Export-SingleBaselineProfile
{
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-BaselineFolderName) }
}
if(-not (Test-Path $path)) { mkdir -Path $path -Force -ErrorAction SilentlyContinue | Out-Null }
if(Test-Path $path)
{
Write-Status "Export $($psObj.displayName)"
$obj = $psObj
if($obj)
{
$fileName = "$path\$((Remove-InvalidFileNameChars $obj.displayName)).json"
ConvertTo-Json $obj -Depth 5 | Out-File $fileName -Force
$settings = Invoke-GraphRequest -Url "/deviceManagement/intents/$($obj.id)/settings"
ConvertTo-Json $settings.value -Depth 5 | Out-File "$path\$($obj.displayName)_Settings.json" -Force
}
$assignments = Invoke-GraphRequest -Url "/deviceManagement/intents/$($obj.id)/assignments"
if(($assignments.Value | measure).Count -gt 0)
{
ConvertTo-Json $assignments.value -Depth 5| Out-File "$path\$($obj.displayName)_assignments.json" -Force
}
$global:exportedObjects++
}
}
function Copy-BaselineProfile
{
if(-not $dgObjects.SelectedItem)
{
[System.Windows.MessageBox]::Show("No object selected`n`nSelect baseline profile you want to copy", "Error", "OK", "Error")
return
}
$ret = Show-InputDialog "Copy baseline profiles" "Select name for the new object" "$($dgObjects.SelectedItem.displayName) - Copy"
if($ret)
{
# Export profile
Write-Status "Export $($dgObjects.SelectedItem.displayName)"
# Convert to Json and back to clone the object
$obj = ConvertTo-Json $dgObjects.SelectedItem.Object -Depth 5 | ConvertFrom-Json
$settings = Invoke-GraphRequest -Url "/deviceManagement/intents/$($obj.id)/settings"
$intentSettings = ConvertTo-Json $settings.value -Depth 5
if($obj)
{
# Import new profile
$obj.displayName = $ret
Import-BaselineProfile $obj $intentSettings | Out-null
$dgObjects.ItemsSource = @(Get-BaselineProfileObjects)
}
Write-Status ""
}
$dgObjects.Focus()
}
function Import-BaselineProfile
{
param($obj, $intentSettings, $templateId)
$json = @"
{
"displayName": "$($obj.displayName)",
"description": "$($obj.description)",
"settingsDelta":
$($intentSettings)
}
"@
if($templateId)
{
$tempId = $templateId
}
else
{
$tempId = $obj.templateId
}
Write-Status "Import $($obj.displayName)"
return Invoke-GraphRequest -Url "/deviceManagement/templates/$($tempId)/createInstance" -Content $json -HttpMethod POST
}
function Import-AllBaselineProfileObjects
{
param(
$path = "$env:Temp"
)
Import-BaselineProfileObjects (Get-JsonFileObjects $path)
}
function Import-BaselineProfileObjects
{
param(
$Objects,
[switch]
$Selected
)
Write-Status "Import terms and conditions"
foreach($obj in $objects)
{
if($Selected -and $obj.Selected -ne $true) { continue }
Write-Log "Import security baseline: $($obj.Object.displayName)"
$assignments = Get-GraphAssignmentsObject $obj.Object ($obj.FileInfo.DirectoryName + "\" + $obj.FileInfo.BaseName + "_assignments.json")
$settingsFile = $obj.FileInfo.DirectoryName + "\" + $obj.FileInfo.BaseName + "_settings.json"
if(-not (Test-Path $settingsFile)) { continue }
$intentSettings = Get-Content $settingsFile -Raw
$response = Import-BaselineProfile $obj.Object $intentSettings
if($response)
{
$global:importedObjects++
Import-GraphAssignments $assignments "assignments" "/deviceManagement/intents/$($response.Id)/assign"
}
}
$dgObjects.ItemsSource = @(Get-BaselineProfileObjects)
Write-Status ""
}

View File

@@ -1,236 +0,0 @@
########################################################
#
# Common module functions
#
########################################################
function Add-ModuleMenuItems
{
Add-MenuItem (New-Object PSObject -Property @{
Title = (Get-IntuneBrandingName)
MenuID = "IntuneGraphAPI"
Script = [ScriptBlock]{Get-IntuneBrandings}
})
}
function Get-SupportedImportObjects
{
$global:importObjects += (New-Object PSObject -Property @{
Selected = $true
Title = (Get-IntuneBrandingName)
Script = [ScriptBlock]{
param($rootFolder)
Write-Status "Import all Intune branding objects"
Import-AllIntuneBrandingObjects (Join-Path $rootFolder (Get-IntuneBrandingFolderName))
}
})
}
function Get-SupportedExportObjects
{
$global:exportObjects += (New-Object PSObject -Property @{
Selected = $true
Title = (Get-IntuneBrandingName)
Script = [ScriptBlock]{
param($rootFolder)
Write-Status "Export all Intune branding objects"
Get-IntuneBrandingObjects | ForEach-Object { Export-SingleIntuneBranding $PSItem.Object (Join-Path $rootFolder (Get-IntuneBrandingFolderName)) }
}
})
}
function Export-AllObjects
{
param($addObjectSubfolder)
$subFolder = ""
if($addObjectSubfolder) { $subFolder = Get-IntuneBrandingFolderName }
}
########################################################
#
# Object specific functions
#
########################################################
function Get-IntuneBrandingName
{
return "Intune Branding"
}
function Get-IntuneBrandingFolderName
{
return "IntuneBranding"
}
function Get-IntuneBrandings
{
Write-Status "Loading banding profiles"
$dgObjects.ItemsSource = @(Get-IntuneBrandingObjects)
#Scriptblocks that will perform the export tasks. empty by default
$script:exportParams = @{}
$script:exportParams.Add("ExportAllScript", [ScriptBlock]{
Export-AllIntuneBrandings $global:txtExportPath.Text
Set-ObjectGrid
Write-Status ""
})
# Same as ExportAllScript since only one object is supported
$script:exportParams.Add("ExportSelectedScript", [ScriptBlock]{
Export-AllIntuneBrandings $global:txtExportPath.Text
Set-ObjectGrid
Write-Status ""
})
#Scriptblock that will perform the import all files
$script:importAll = [ScriptBlock]{
Import-AllIntuneBrandingObjects $global:txtImportPath.Text
Set-ObjectGrid
}
#Scriptblock that will perform the import of selected files
$script:importSelected = [ScriptBlock]{
Import-IntuneBrandingObjects $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})
}
function Get-IntuneBrandingObjects
{
Get-GraphObjects -Url "/deviceManagement/intuneBrand" -property @("displayName")
}
function Export-AllIntuneBrandings
{
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-SingleIntuneBranding $objTmp.Object $path
}
}
}
function Export-SingleIntuneBranding
{
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-IntuneBrandingFolderName) }
}
if(-not (Test-Path $path)) { mkdir -Path $path -Force -ErrorAction SilentlyContinue | Out-Null }
if(Test-Path $path)
{
Write-Status "Export $($psObj.displayName)"
$obj = $psObj
if($obj)
{
$fileName = "$path\$((Remove-InvalidFileNameChars $obj.displayName)).json"
ConvertTo-Json $obj -Depth 5 | Out-File $fileName -Force
Save-IntuneBrandingFile $obj "lightBackgroundLogo" $path
Save-IntuneBrandingFile $obj "darkBackgroundLogo" $path
Save-IntuneBrandingFile $obj "landingPageCustomizedImage" $path
}
$global:exportedObjects++
}
}
function Save-IntuneBrandingFile
{
param($obj, $prop, $path)
if(-not $obj.$prop.type) { return }
$arr=$obj.$prop.type.Split('/')
if($arr.Length -gt 1)
{
$fileType = $arr[1]
}
else
{
$fileType = ".jpg" # assume...
}
$fileName = "$path\$((Remove-InvalidFileNameChars "$($obj.displayName).$prop.$fileType"))"
try
{
if(Test-Path $fileName)
{
Remove-Item -Path $fileName -Force
}
[IO.File]::WriteAllBytes($fileName, [System.Convert]::FromBase64String($obj.$prop.value))
}
catch {}
}
function Import-IntuneBranding
{
param($obj)
Start-PreImport $obj -RemoveProperties @("@odata.context")
$newObject = @"
{
"intuneBrand":$((ConvertTo-Json $obj -Depth 5))
}
"@
Write-Status "Import $($obj.displayName)"
# Note: Branding is imported to deviceManagement with JSON parent object intuneBrand
Invoke-GraphRequest -Url "$URL/deviceManagement" -Content $newObject -HttpMethod PATCH
}
function Import-AllIntuneBrandingObjects
{
param($path = "$env:Temp")
Import-IntuneBrandingObjects (Get-JsonFileObjects $path)
}
function Import-IntuneBrandingObjects
{
param(
$Objects,
[switch]
$Selected
)
Write-Status "Import Intune branding"
foreach($obj in $objects)
{
if($Selected -and $obj.Selected -ne $true) { continue }
Write-Log "Import Intune branding"
$response = Import-IntuneBranding $obj.Object
# Note: No assignments for branding. This is default branding for everyone
}
$dgObjects.ItemsSource = @(Get-IntuneBrandingObjects)
Write-Status ""
}

View File

@@ -1,255 +0,0 @@
########################################################
#
# Common module functions
#
########################################################
function Add-ModuleMenuItems
{
Add-MenuItem (New-Object PSObject -Property @{
Title = (Get-CompliancePolicyName)
MenuID = "IntuneGraphAPI"
Script = [ScriptBlock]{Get-CompliancePolicies}
})
}
function Get-SupportedImportObjects
{
$global:importObjects += (New-Object PSObject -Property @{
Selected = $true
Title = (Get-CompliancePolicyName)
Script = [ScriptBlock]{
param($rootFolder)
Write-Status "Import all Intune compliance policies"
Import-AllCompliancePolicyObjects (Join-Path $rootFolder (Get-CompliancePolicyFolderName))
}
})
}
function Get-SupportedExportObjects
{
$global:exportObjects += (New-Object PSObject -Property @{
Selected = $true
Title = (Get-CompliancePolicyName)
Script = [ScriptBlock]{
param($rootFolder)
Write-Status "Export all compliance policies"
Get-CompliancePolicyObjects | ForEach-Object { Export-SingleCompliancePolicy $PSItem.Object (Join-Path $rootFolder (Get-CompliancePolicyFolderName)) }
}
})
}
function Export-AllObjects
{
param($addObjectSubfolder)
$subFolder = ""
if($addObjectSubfolder) { $subFolder = Get-CompliancePolicyFolderName }
}
########################################################
#
# Object specific functions
#
########################################################
function Get-CompliancePolicyName
{
return "Compliance Policies"
}
function Get-CompliancePolicyFolderName
{
return "CompliancePolicies"
}
function Get-CompliancePolicies
{
Write-Status "Loading compliance policies"
$dgObjects.ItemsSource = @(Get-CompliancePolicyObjects)
#Scriptblocks that will perform the export tasks. empty by default
$script:exportParams = @{}
$script:exportParams.Add("ExportAllScript", [ScriptBlock]{
Export-AllCompliancePolicies $global:txtExportPath.Text
Set-ObjectGrid
Write-Status ""
})
$script:exportParams.Add("ExportSelectedScript", [ScriptBlock]{
Export-SelectedCompliancePolicy $global:txtExportPath.Text
Set-ObjectGrid
Write-Status ""
})
#Scriptblock that will perform the import all files
$script:importAll = [ScriptBlock]{
Import-AllCompliancePolicyObjects $global:txtImportPath.Text
Set-ObjectGrid
}
#Scriptblock that will perform the import of selected files
$script:importSelected = [ScriptBlock]{
Import-CompliancePolicyObjects $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}) -copy ([scriptblock]{Copy-CompliancePolicy}) -ViewFullObject ([scriptblock]{Get-CompliancePolicyObject $global:dgObjects.SelectedItem.Object})
}
function Get-CompliancePolicyObjects
{
Get-GraphObjects -Url "/deviceManagement/deviceCompliancePolicies"
}
function Get-CompliancePolicyObject
{
param($object, $additional = "")
if(-not $Object.id) { return }
Invoke-GraphRequest -Url "/deviceManagement/deviceCompliancePolicies/$($Object.id)$additional"
}
function Export-AllCompliancePolicies
{
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-SingleCompliancePolicy $objTmp.Object $path
}
}
}
function Export-SelectedCompliancePolicy
{
param($path = "$env:Temp")
Export-SingleCompliancePolicy $global:dgObjects.SelectedItem.Object $path
}
function Export-SingleCompliancePolicy
{
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-CompliancePolicyFolderName) }
}
if(-not (Test-Path $path)) { mkdir -Path $path -Force -ErrorAction SilentlyContinue | Out-Null }
if(Test-Path $path)
{
Write-Status "Export $($psObj.displayName)"
$obj = Invoke-GraphRequest -Url "/deviceManagement/deviceCompliancePolicies/$($psObj.id)?`$expand=assignments"
if($obj)
{
$fileName = "$path\$((Remove-InvalidFileNameChars $obj.displayName)).json"
ConvertTo-Json $obj -Depth 5 | Out-File $fileName -Force
Add-MigrationInfo $obj.assignments
}
$global:exportedObjects++
}
}
function Copy-CompliancePolicy
{
if(-not $dgObjects.SelectedItem)
{
[System.Windows.MessageBox]::Show("No object selected`n`nSelect compliance policy item you want to copy", "Error", "OK", "Error")
return
}
$ret = Show-InputDialog "Copy compliance policy" "Select name for the new object" "$($dgObjects.SelectedItem.displayName) - Copy"
if($ret)
{
# Export profile
Write-Status "Export $($dgObjects.SelectedItem.displayName)"
# Convert to Json and back to clone the object
$obj = ConvertTo-Json $dgObjects.SelectedItem.Object -Depth 5 | ConvertFrom-Json
if($obj)
{
# Import new profile
$obj.displayName = $ret
Import-CompliancePolicy $obj | Out-null
$dgObjects.ItemsSource = @(Get-CompliancePolicyObjects)
}
Write-Status ""
}
$dgObjects.Focus()
}
function Import-CompliancePolicy
{
param($obj)
Start-PreImport $obj
$json = ConvertTo-Json $obj -Depth 5
$json = $json.Trim().TrimEnd('}').Trim()
$json += @"
,
"scheduledActionsForRule":[{"ruleName":"PasswordRequired","scheduledActionConfigurations":[{"actionType":"block","gracePeriodHours":0,"notificationTemplateId":"","notificationMessageCCList":[]}]}]
}
"@
Write-Status "Import $($obj.displayName)"
Invoke-GraphRequest -Url "/deviceManagement/deviceCompliancePolicies" -Content $json -HttpMethod POST
}
function Import-AllCompliancePolicyObjects
{
param($path = "$env:Temp")
Import-CompliancePolicyObjects (Get-JsonFileObjects $path)
}
function Import-CompliancePolicyObjects
{
param(
$Objects,
[switch]
$Selected
)
Write-Status "Import compliance policies"
foreach($obj in $objects)
{
if($Selected -and $obj.Selected -ne $true) { continue }
Write-Log "Import Compliance Policy: $($obj.Object.displayName)"
$assignments = Get-GraphAssignmentsObject $obj.Object ($obj.FileInfo.DirectoryName + "\" + $obj.FileInfo.BaseName + "_assignments.json")
$response = Import-CompliancePolicy $obj.Object
if($response)
{
$global:importedObjects++
Import-GraphAssignments $assignments "assignments" "/deviceManagement/deviceCompliancePolicies/$($response.Id)/assign"
}
}
$dgObjects.ItemsSource = @(Get-CompliancePolicyObjects)
Write-Status ""
}

View File

@@ -1,291 +0,0 @@
########################################################
#
# 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
#>

View File

@@ -1,251 +0,0 @@
########################################################
#
# Common module functions
#
########################################################
function Add-ModuleMenuItems
{
Add-MenuItem (New-Object PSObject -Property @{
Title = (Get-DeviceConfigurationName)
MenuID = "IntuneGraphAPI"
Script = [ScriptBlock]{Get-DeviceConfigurations}
})
}
function Get-SupportedImportObjects
{
$global:importObjects += (New-Object PSObject -Property @{
Selected = $true
Title = (Get-DeviceConfigurationName)
Script = [ScriptBlock]{
param($rootFolder)
Write-Status "Import all device configuration objects"
Import-AllDeviceConfigurationObjects (Join-Path $rootFolder (Get-DeviceConfigurationFolderName))
}
})
}
function Get-SupportedExportObjects
{
$global:exportObjects += (New-Object PSObject -Property @{
Selected = $true
Title = (Get-DeviceConfigurationName)
Script = [ScriptBlock]{
param($rootFolder)
Write-Status "Export all device configuration objects"
Get-DeviceConfigurationObjects | ForEach-Object { Export-SingleDeviceConfiguration $PSItem.Object (Join-Path $rootFolder (Get-DeviceConfigurationFolderName)) }
}
})
}
function Export-AllObjects
{
param($addObjectSubfolder)
$subFolder = ""
if($addObjectSubfolder) { $subFolder = Get-DeviceConfigurationFolderName }
}
########################################################
#
# Object specific functions
#
########################################################
function Get-DeviceConfigurationName
{
return "Device Configurations"
}
function Get-DeviceConfigurationFolderName
{
return "DeviceConfigurations"
}
function Get-DeviceConfigurations
{
Write-Status "Loading device configurations"
$dgObjects.ItemsSource = @(Get-DeviceConfigurationObjects)
#Scriptblocks that will perform the export tasks. empty by default
$script:exportParams = @{}
$script:exportParams.Add("ExportAllScript", [ScriptBlock]{
Export-AllDeviceConfigurations $global:txtExportPath.Text
Set-ObjectGrid
Write-Status ""
})
$script:exportParams.Add("ExportSelectedScript", [ScriptBlock]{
Export-SelectedDeviceConfiguration $global:txtExportPath.Text
Set-ObjectGrid
Write-Status ""
})
#Scriptblock that will perform the import all files
$script:importAll = [ScriptBlock]{
Import-AllDeviceConfigurationObjects $global:txtImportPath.Text
Set-ObjectGrid
}
#Scriptblock that will perform the import of selected files
$script:importSelected = [ScriptBlock]{
Import-DeviceConfigurationObjects $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}) -copy ([scriptblock]{Copy-DeviceConfiguration}) -ViewFullObject ([scriptblock]{Get-DeviceConfigurationObject $global:dgObjects.SelectedItem.Object})
}
function Get-DeviceConfigurationObjects
{
Get-GraphObjects -Url "/deviceManagement/deviceConfigurations"#,"/deviceManagement/groupPolicyConfigurations"
}
function Get-DeviceConfigurationObject
{
param($object, $additional = "")
if(-not $Object.id) { return }
Invoke-GraphRequest -Url "/deviceManagement/deviceConfigurations/$($Object.id)$additional"
}
function Export-AllDeviceConfigurations
{
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-SingleDeviceConfiguration $objTmp.Object $path
}
}
}
function Export-SelectedDeviceConfiguration
{
param($path = "$env:Temp")
Export-SingleDeviceConfiguration $global:dgObjects.SelectedItem.Object $path
}
function Export-SingleDeviceConfiguration
{
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-DeviceConfigurationFolderName) }
}
if(-not (Test-Path $path)) { mkdir -Path $path -Force -ErrorAction SilentlyContinue | Out-Null }
if(Test-Path $path)
{
Write-Status "Export $($psObj.displayName)"
$obj = Invoke-GraphRequest -Url "/deviceManagement/deviceConfigurations/$($psObj.id)?`$expand=assignments"
if($obj)
{
$fileName = "$path\$((Remove-InvalidFileNameChars $obj.displayName)).json"
ConvertTo-Json $obj -Depth 5 | Out-File $fileName -Force
if($script:chkExportScript.IsChecked)
{
$fileName = "$path\$($obj.FileName)"
[System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String($obj.scriptContent)) | Out-File $fileName -Force
}
Add-MigrationInfo $obj.assignments
$global:exportedObjects++
}
}
}
function Copy-DeviceConfiguration
{
if(-not $dgObjects.SelectedItem)
{
[System.Windows.MessageBox]::Show("No object selected`n`nSelect device configuration item you want to copy", "Error", "OK", "Error")
return
}
$ret = Show-InputDialog "Copy device configuration" "Select name for the new object" "$($dgObjects.SelectedItem.displayName) - Copy"
if($ret)
{
# Export profile
Write-Status "Export $($dgObjects.SelectedItem.displayName)"
# Convert to Json and back to clone the object
$obj = ConvertTo-Json $dgObjects.SelectedItem.Object -Depth 5 | ConvertFrom-Json
if($obj)
{
# Import new profile
$obj.displayName = $ret
Import-DeviceConfiguration $obj | Out-Null
$dgObjects.ItemsSource = @(Get-DeviceConfigurationObjects)
}
Write-Status ""
}
$dgObjects.Focus()
}
function Import-DeviceConfiguration
{
param($obj)
Write-Status "Import $($obj.displayName)"
Start-PreImport $obj
Invoke-GraphRequest -Url "/deviceManagement/deviceConfigurations" -Content (ConvertTo-Json $obj -Depth 5) -HttpMethod POST
}
function Import-AllDeviceConfigurationObjects
{
param($path = "$env:Temp")
Import-DeviceConfigurationObjects (Get-JsonFileObjects $path)
}
function Import-DeviceConfigurationObjects
{
param(
$Objects,
[switch]
$Selected
)
Write-Status "Import device configuration profiles"
foreach($obj in $objects)
{
if($Selected -and $obj.Selected -ne $true) { continue }
Write-Log "Import device configuration policy: $($obj.Object.displayName)"
$assignments = Get-GraphAssignmentsObject $obj.Object ($obj.FileInfo.DirectoryName + "\" + $obj.FileInfo.BaseName + "_assignments.json")
$response = Import-DeviceConfiguration $obj.Object
if($response)
{
$global:importedObjects++
Import-GraphAssignments $assignments "assignments" "/deviceManagement/deviceConfigurations/$($response.Id)/assign"
}
}
$dgObjects.ItemsSource = @(Get-DeviceConfigurationObjects)
Write-Status ""
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,104 @@
<#
.SYNOPSIS
Module for read-only Intune objects
.DESCRIPTION
This module is for the Endpoint Info View. It shows read-only objects in Intune
.NOTES
Author: Mikael Karlsson
#>
function Get-ModuleVersion
{
'3.0.0'
}
function Invoke-InitializeModule
{
#Add menu group and items
$global:EMInfoViewObject = (New-Object PSObject -Property @{
Title = "Intune Info"
Description = "Displays read-only information in Intune."
ID = "EMInfoGraphAPI"
ViewPanel = $viewPanel
ItemChanged = { Show-GraphObjects; Write-Status ""}
Activating = { Invoke-EMInfoActivatingView }
Authentication = (Get-MSALAuthenticationObject)
Authenticate = { Invoke-EMInfoAuthenticateToMSAL }
AppInfo = (Get-GraphAppInfo "EM" "d1ddf0e4-d672-4dae-b554-9d5bdfd93547")
SaveSettings = { Invoke-EMSaveSettings }
})
Add-ViewObject $global:EMInfoViewObject
Add-ViewItem (New-Object PSObject -Property @{
Title = "Baseline Templates"
Id = "BaselineTemplates"
ViewID = "EMInfoGraphAPI"
API = "/deviceManagement/templates"
ShowButtons = @("View")
Permissons=@("DeviceManagementConfiguration.ReadWrite.All")
Icon="EndpointSecurity"
})
Add-ViewItem (New-Object PSObject -Property @{
Title = "Android Google Play"
Id = "AndroidGooglePlay"
ViewID = "EMInfoGraphAPI"
ViewProperties = @("bindStatus", "lastAppSyncDateTime", "ownerUserPrincipalName")
API = "/deviceManagement/androidManagedStoreAccountEnterpriseSettings"
ShowButtons = @("View")
Permissons=@("DeviceManagementConfiguration.ReadWrite.All")
})
Add-ViewItem (New-Object PSObject -Property @{
Title = "Android Enrolment Profiles"
Id = "AndroidEnrolmentProfiles"
ViewID = "EMInfoGraphAPI"
API = "deviceManagement/androidDeviceOwnerEnrollmentProfiles"
ShowButtons = @("View")
Permissons=@("DeviceManagementConfiguration.ReadWrite.All")
Icon = "AndroidCOWP"
})
Add-ViewItem (New-Object PSObject -Property @{
Title = "Apple VPP Tokens"
Id = "AppleVPPTokens"
ViewID = "EMInfoGraphAPI"
ViewProperties = @("appleId", "state", "appleId", "id")
API = "/deviceAppManagement/vppTokens"
ShowButtons = @("View")
Permissons=@("DeviceManagementConfiguration.ReadWrite.All")
})
Add-ViewItem (New-Object PSObject -Property @{
Title = "Apple Enrollment Tokens"
Id = "AppleEnrollmentTokens"
ViewID = "EMInfoGraphAPI"
ViewProperties = @("tokenName", "appleIdentifier", "tokenExpirationDateTime", "id")
API = "/deviceManagement/depOnboardingSettings/?`$top=100"
ShowButtons = @("View")
Permissons=@("DeviceManagementServiceConfig.ReadWrite.All")
})
}
function Invoke-EMInfoActivatingView
{
if(-not $global:EMInfoViewObject.ViewPanel)
{
# Use the same view panel as Intune Manager
$global:EMInfoViewObject.ViewPanel = $global:EMViewObject.ViewPanel
}
}
function Invoke-EMInfoAuthenticateToMSAL
{
$global:EMInfoViewObject.AppInfo = Get-GraphAppInfo "EMAzureApp" "d1ddf0e4-d672-4dae-b554-9d5bdfd93547"
Set-MSALCurrentApp $global:EMInfoViewObject.AppInfo
$usr = (?? $global:MSALToken.Account.UserName (Get-Setting "" "LastLoggedOnUser"))
if($usr)
{
& $global:msalAuthenticator.Login -Account $usr
}
}

View File

@@ -1,288 +0,0 @@
########################################################
#
# Common module functions
#
########################################################
function Add-ModuleMenuItems
{
Add-MenuItem (New-Object PSObject -Property @{
Title = (Get-ESPName)
MenuID = "IntuneGraphAPI"
Script = [ScriptBlock]{Get-ESPs}
})
}
function Get-SupportedImportObjects
{
$global:importObjects += (New-Object PSObject -Property @{
Selected = $true
Title = (Get-ESPName)
Script = [ScriptBlock]{
param($rootFolder)
Write-Status "Import all enrollment status page settings"
Import-AllESPObjects (Join-Path $rootFolder (Get-ESPFolderName))
}
})
}
function Get-SupportedExportObjects
{
$global:exportObjects += (New-Object PSObject -Property @{
Selected = $true
Title = (Get-ESPName)
Script = [ScriptBlock]{
param($rootFolder)
Write-Status "Export all enrollment status page settings"
Get-ESPObjects | ForEach-Object { Export-SingleESP $PSItem.Object (Join-Path $rootFolder (Get-ESPFolderName)) }
}
})
}
function Export-AllObjects
{
param($addObjectSubfolder)
$subFolder = ""
if($addObjectSubfolder) { $subFolder = Get-ESPFolderName }
}
########################################################
#
# Object specific functions
#
########################################################
function Get-ESPName
{
return "Enrollment Status Page"
}
function Get-ESPFolderName
{
return "EnrollmentStatusPage"
}
function Get-ESPs
{
Write-Status "Loading enrollment status page objects"
$dgObjects.ItemsSource = @(Get-ESPObjects)
#Scriptblocks that will perform the export tasks. empty by default
$script:exportParams = @{}
$script:exportParams.Add("ExportAllScript", [ScriptBlock]{
Export-AllESPs $global:txtExportPath.Text
Set-ObjectGrid
Write-Status ""
})
$script:exportParams.Add("ExportSelectedScript", [ScriptBlock]{
Export-SelectedESP $global:txtExportPath.Text
Set-ObjectGrid
Write-Status ""
})
#Scriptblock that will perform the import all files
$script:importAll = [ScriptBlock]{
Import-AllESPObjects $global:txtExportPath.Text
Set-ObjectGrid
}
#Scriptblock that will perform the import of selected files
$script:importSelected = [ScriptBlock]{
Import-ESPObjects $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}) -copy ([scriptblock]{Copy-ESP}) -ViewFullObject ([scriptblock]{Get-ESPObject $global:dgObjects.SelectedItem.Object})
}
function Get-ESPObjects
{
Get-GraphObjects -Url "/deviceManagement/deviceEnrollmentConfigurations"
}
function Get-ESPObject
{
param($object, $additional = "")
if(-not $Object.id) { return }
Invoke-GraphRequest -Url "/deviceManagement/deviceEnrollmentConfigurations/$($Object.id)$additional"
}
function Export-AllESPs
{
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-SingleESP $objTmp.Object $path
}
}
}
function Export-SelectedESP
{
param($path = "$env:Temp")
Export-SingleESP $global:dgObjects.SelectedItem.Object $path
}
function Export-SingleESP
{
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-ESPFolderName) }
}
if(-not (Test-Path $path)) { mkdir -Path $path -Force -ErrorAction SilentlyContinue | Out-Null }
if(Test-Path $path)
{
Write-Status "Export $($psObj.displayName)"
$obj = Invoke-GraphRequest -Url "/deviceManagement/deviceEnrollmentConfigurations/$($psObj.id)" #?`$expand=assignments"
if($obj)
{
if($obj.id -like "*_default*")
{
$idx = $obj.id.ToLower().IndexOf("_default")
$baseName = "Default_" + $obj.id.SubString($idx + "_default".Length)
}
else
{
# ?`$expand=assignments is not working so get assignments
$assignments = Invoke-GraphRequest -Url "/deviceManagement/deviceEnrollmentConfigurations/$($obj.id)/assignments"
if($assignments.value)
{
$obj | Add-Member -NotePropertyName "assignments" -NotePropertyValue $assignments.value
}
$baseName = Remove-InvalidFileNameChars $obj.displayName
}
$fileName = "$path\$baseName.json"
ConvertTo-Json $obj -Depth 5 | Out-File $fileName -Force
Add-MigrationInfo $obj.assignments
}
$global:exportedObjects++
}
}
function Copy-ESP
{
if(-not $dgObjects.SelectedItem)
{
[System.Windows.MessageBox]::Show("No object selected`n`nSelect enrollment status page item you want to copy", "Error", "OK", "Error") | Out-Null
return
}
if($dgObjects.SelectedItem.Object.id -like "*_default*")
{
[System.Windows.MessageBox]::Show("You cannot copy default items`n`nSelect custom entrollment status page item", "Error", "OK", "Error") | Out-Null
return
}
$ret = Show-InputDialog "Copy enrollment status page" "Select name for the new object" "$($dgObjects.SelectedItem.displayName) - Copy"
if($ret)
{
# Export profile
Write-Status "Export $($dgObjects.SelectedItem.displayName)"
# Convert to Json and back to clone the object
$obj = ConvertTo-Json $dgObjects.SelectedItem.Object -Depth 5 | ConvertFrom-Json
if($obj)
{
# Import new profile
$obj.displayName = $ret
Import-ESP $obj | Out-Null
$dgObjects.ItemsSource = @(Get-ESPObjects)
}
Write-Status ""
}
$dgObjects.Focus()
}
function Import-ESP
{
param($obj)
Start-PreImport $obj
if($obj.id -like "*_default*")
{
Write-Status "Update $($obj.displayName)"
Invoke-GraphRequest -Url "/deviceManagement/deviceEnrollmentConfigurations/$($obj.id)" -Content (ConvertTo-Json $obj -Depth 5) -HttpMethod PATCH
}
else
{
Write-Status "Import $($obj.displayName)"
Invoke-GraphRequest -Url "/deviceManagement/deviceEnrollmentConfigurations" -Content (ConvertTo-Json $obj -Depth 5) -HttpMethod POST
}
}
function Import-AllESPObjects
{
param($path = "$env:Temp")
Import-ESPObjects (Get-JsonFileObjects $path)
}
function Import-ESPObjects
{
param(
$Objects,
[switch]
$Selected
)
Write-Status "Import enrollment status page"
foreach($obj in $Objects)
{
if($Selected -and $obj.Selected -ne $true) { continue }
if($obj.Object.id -like "*_default*")
{
$idx = $obj.Object.id.ToLower().IndexOf("_default")
$extInfo = " ($($obj.Object.id.SubString($idx + "_default".Length)))"
}
else
{
$extInfo = ""
}
Write-Log "Import Enrollment Status Page: $($obj.Object.displayName)$extInfo"
$assignments = Get-GraphAssignmentsObject $obj.Object ($obj.FileInfo.DirectoryName + "\" + $obj.FileInfo.BaseName + "_assignments.json")
$response = Import-ESP $obj.Object
if($response)
{
$global:importedObjects++
Import-GraphAssignments $assignments "enrollmentConfigurationAssignments" "/deviceManagement/deviceEnrollmentConfigurations/$($response.Id)/assign"
}
}
$dgObjects.ItemsSource = @(Get-ESPObjects)
Write-Status ""
}

View File

@@ -1,335 +0,0 @@
########################################################
#
# Common module functions
#
########################################################
function Add-ModuleMenuItems
{
Add-MenuItem (New-Object PSObject -Property @{
Title = (Get-GPOSettingName)
MenuID = "IntuneGraphAPI"
Script = [ScriptBlock]{Get-GPOSettings}
})
}
function Get-SupportedImportObjects
{
$global:importObjects += (New-Object PSObject -Property @{
Selected = $true
Title = (Get-GPOSettingName)
Script = [ScriptBlock]{
param($rootFolder)
Write-Status "Import all administrative templates"
Import-AllGPOSettingObjects (Join-Path $rootFolder (Get-GPOSettingFolderName))
}
})
}
function Get-SupportedExportObjects
{
$global:exportObjects += (New-Object PSObject -Property @{
Selected = $true
Title = (Get-GPOSettingName)
Script = [ScriptBlock]{
param($rootFolder)
Write-Status "Export all administrative templates"
Get-GPOSettingObjects | ForEach-Object { Export-SingleGPOSetting $PSItem.Object (Join-Path $rootFolder (Get-GPOSettingFolderName)) }
}
})
}
function Export-AllObjects
{
param($addObjectSubfolder)
$subFolder = ""
if($addObjectSubfolder) { $subFolder = Get-GPOSettingFolderName }
}
########################################################
#
# Object specific functions
#
########################################################
function Get-GPOSettingName
{
return "Administrative Templates"
}
function Get-GPOSettingFolderName
{
return "AdministrativeTemplates"
}
function Get-GPOSettings
{
Write-Status "Loading administrative templates"
$dgObjects.ItemsSource = @(Get-GPOSettingObjects)
#Scriptblocks that will perform the export tasks. empty by default
$script:exportParams = @{}
$script:exportParams.Add("ExportAllScript", [ScriptBlock]{
Export-AllGPOSettings $global:txtExportPath.Text
Set-ObjectGrid
Write-Status ""
})
$script:exportParams.Add("ExportSelectedScript", [ScriptBlock]{
Export-SelectedGPOSetting $global:txtExportPath.Text
Set-ObjectGrid
Write-Status ""
})
#Scriptblock that will perform the import all files
$script:importAll = [ScriptBlock]{
Import-AllGPOSettingObjects $global:txtImportPath.Text
Set-ObjectGrid
}
#Scriptblock that will perform the import of selected files
$script:importSelected = [ScriptBlock]{
Import-GPOSettingObjects $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}) -copy ([scriptblock]{Copy-GPOSetting}) -ViewFullObject ([scriptblock]{Get-GPOSettingObject $global:dgObjects.SelectedItem.Object})
}
function Get-GPOSettingObjects
{
Get-GraphObjects -Url "/deviceManagement/groupPolicyConfigurations"
}
function Get-GPOSettingObject
{
param($object, $additional = "")
if(-not $Object.id) { return }
@((Invoke-GraphRequest -Url "/deviceManagement/groupPolicyConfigurations/$($Object.id)$additional"),(Get-GPOObjectSettings $Object))
}
function Export-AllGPOSettings
{
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-SingleGPOSetting $objTmp.Object $path
}
}
}
function Export-SelectedGPOSetting
{
param($path = "$env:Temp")
Export-SingleGPOSetting $global:dgObjects.SelectedItem.Object $path
}
function Get-GPOObjectSettings
{
param($GPOObj)
$gpoSettings = @()
# Get all configured policies in the Administrative Templates profile
$GPODefinitionValues = Invoke-GraphRequest -Url "/deviceManagement/groupPolicyConfigurations/$($GPOObj.id)/definitionValues?`$expand=definition"
foreach($definitionValue in $GPODefinitionValues.value)
{
# Get presentation values for the current settings (with presentation object included)
$presentationValues = Invoke-GraphRequest -Url "/deviceManagement/groupPolicyConfigurations/$($GPOObj.id)/definitionValues/$($definitionValue.id)/presentationValues?`$expand=presentation"
# Set base policy settings
$obj = @{
"enabled" = $definitionValue.enabled
"definition@odata.bind" = "$($global:graphURL)/deviceManagement/groupPolicyDefinitions('$($definitionValue.definition.id)')"
}
if($presentationValues.value)
{
# Policy presentation values set e.g. a drop down list, check box, text box etc.
$obj.presentationValues = @()
$presentations = $null
foreach ($presentationValue in $presentationValues.value)
{
# Add presentation@odata.bind property that links the value to the presentation object
$presentationValue | Add-Member -MemberType NoteProperty -Name "presentation@odata.bind" -Value "$($global:graphURL)/deviceManagement/groupPolicyDefinitions('$($definitionValue.definition.id)')/presentations('$($presentationValue.presentation.id)')"
#Remove presentation object so it is not included in the export
Remove-ObjectProperty $presentationValue "presentation"
#Optional removes. Import will igonre them
Remove-ObjectProperty $presentationValue "id"
Remove-ObjectProperty $presentationValue "lastModifiedDateTime"
Remove-ObjectProperty $presentationValue "createdDateTime"
# Add presentation value to the list
$obj.presentationValues += $presentationValue
}
}
$gpoSettings += $obj
}
$gpoSettings
}
function Export-SingleGPOSetting
{
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-GPOSettingFolderName) }
}
if(-not (Test-Path $path)) { mkdir -Path $path -Force -ErrorAction SilentlyContinue | Out-Null }
if(Test-Path $path)
{
Write-Status "Export $($psObj.displayName)"
$obj = Invoke-GraphRequest -Url "deviceManagement/groupPolicyConfigurations/$($psObj.Id)?`$expand=assignments"
if($obj)
{
# Save Administrative Templates profile
ConvertTo-Json $obj -Depth 5 | Out-File "$path\$((Remove-InvalidFileNameChars $obj.displayName)).json" -Force
# Collect and save all the settings of the Administrative Templates profile
$gpoSettings = Get-GPOObjectSettings $obj
ConvertTo-Json $gpoSettings -Depth 5 | Out-File "$path\$($obj.displayName)_Settings.json" -Force
# Export assignment info
Add-MigrationInfo $obj.assignments
}
$global:exportedObjects++
}
}
function Copy-GPOSetting
{
if(-not $dgObjects.SelectedItem)
{
[System.Windows.MessageBox]::Show("No object selected`n`nSelect administrative templates profile you want to copy", "Error", "OK", "Error")
return
}
$ret = Show-InputDialog "Copy administrative template" "Select name for the new profile" "$($dgObjects.SelectedItem.displayName) - Copy"
if($ret)
{
# Export profile
Write-Status "Export $($dgObjects.SelectedItem.displayName)"
# Convert to Json and back to clone the object
$obj = ConvertTo-Json $dgObjects.SelectedItem.Object -Depth 5 | ConvertFrom-Json
if($obj)
{
# Get the settings of the profile
$gpoSettings = Get-GPOObjectSettings $obj
# Import the new profile
$obj.displayName = $ret
Import-GPOSetting $obj $gpoSettings | Out-Null
#Reload objects
$dgObjects.ItemsSource = @(Get-GPOSettingObjects)
}
Write-Status ""
}
$dgObjects.Focus()
}
function Import-GPOSetting
{
param($obj, $settings)
Write-Status "Import $($obj.displayName)"
Start-PreImport $obj
# Import Administrative Template profile
$response = Invoke-GraphRequest -Url "/deviceManagement/groupPolicyConfigurations" -Content (ConvertTo-Json $obj -Depth 5) -HttpMethod POST
if($response)
{
foreach($setting in $settings)
{
Start-PreImport $setting
# Import each setting for the Administrative Template profile
$response2 = Invoke-GraphRequest -Url "/deviceManagement/groupPolicyConfigurations/$($response.id)/definitionValues" -Content (ConvertTo-Json $setting -Depth 5) -HttpMethod POST
}
}
$response
}
function Import-AllGPOSettingObjects
{
param($path = "$env:Temp")
# Read json files and import all objects
# Note: Each json file must match the object type being imported
Import-GPOSettingObjects (Get-JsonFileObjects $path)
}
function Import-GPOSettingObjects
{
param(
$Objects,
[switch]
$Selected
)
Write-Status "Import administrative template profile"
foreach($obj in $objects)
{
if($Selected -and $obj.Selected -ne $true) { continue }
Write-Log "Import Administrative Template: $($obj.Object.displayName)"
$gpoSettings = $null
# Load settings from the <AdminTeplateName>_settings.json file
$settingsFile = ($obj.FileInfo.DirectoryName + "\" + $obj.FileInfo.BaseName + "_settings.json")
if(Test-Path $settingsFile)
{
$gpoSettings = (ConvertFrom-Json (Get-Content $settingsFile -Raw))
}
# Get assignment settings
$assignments = Get-GraphAssignmentsObject $obj.Object ($obj.FileInfo.DirectoryName + "\" + $obj.FileInfo.BaseName + "_assignments.json")
# Import Administrative Template object
$response = Import-GPOSetting $obj.Object $gpoSettings
if($response)
{
$global:importedObjects++
# Import assignments
Import-GraphAssignments $assignments "assignments" "/deviceManagement/groupPolicyConfigurations/$($response.Id)/assign"
}
}
#Reload list of objects
$dgObjects.ItemsSource = @(Get-GPOSettingObjects)
Write-Status ""
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,224 +0,0 @@
########################################################
#
# Common module functions
#
########################################################
function Add-ModuleMenuItems
{
Add-MenuItem (New-Object PSObject -Property @{
Title = (Get-MDMMAMName)
MenuID = "IntuneGraphAPI"
Script = [ScriptBlock]{Get-MDMMAM}
})
}
function Get-SupportedImportObjects
{
$global:importObjects += (New-Object PSObject -Property @{
Selected = $true
Title = (Get-MDMMAMName)
Script = [ScriptBlock]{
param($rootFolder)
Write-Status "Import all MDM/MAM setting"
Import-AllMDMMAMObjects (Join-Path $rootFolder (Get-MDMMAMFolderName))
}
})
}
function Get-SupportedExportObjects
{
$global:exportObjects += (New-Object PSObject -Property @{
Selected = $true
Title = (Get-MDMMAMName)
Script = [ScriptBlock]{
param($rootFolder)
Write-Status "Export all MDM/MAM settings"
Get-MDMMAMObjects | ForEach-Object { Export-SingleMDMMAM $PSItem.Object (Join-Path $rootFolder (Get-MDMMAMFolderName)) }
}
})
}
function Export-AllObjects
{
param($addObjectSubfolder)
$subFolder = ""
if($addObjectSubfolder) { $subFolder = Get-MDMMAMFolderName }
}
########################################################
#
# Object specific functions
#
########################################################
function Get-MDMMAMName
{
return "MDM/MAM"
}
function Get-MDMMAMFolderName
{
return "MDMMAM"
}
function Get-MDMMAM
{
Write-Status "Loading MDM/MAM object"
$dgObjects.ItemsSource = @(Get-MDMMAMObjects)
#Scriptblocks that will perform the export tasks. empty by default
$script:exportParams = @{}
$script:exportParams.Add("ExportAllScript", [ScriptBlock]{
Export-AllMDMMAM $global:txtExportPath.Text
Set-ObjectGrid
Write-Status ""
})
$script:exportParams.Add("ExportSelectedScript", [ScriptBlock]{
Export-SelectedMDMMAM $global:txtExportPath.Text
Set-ObjectGrid
Write-Status ""
})
#Scriptblock that will perform the import all files
$script:importAll = [ScriptBlock]{
Import-AllMDMMAMObjects $global:txtImportPath.Text
Set-ObjectGrid
}
#Scriptblock that will perform the import of selected files
$script:importSelected = [ScriptBlock]{
Import-MDMMAMObjects $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-MDMMAMObject $global:dgObjects.SelectedItem.Object})
}
function Get-MDMMAMObjects
{
Get-AzureNativeObjects "MdmApplications" -property @('appDisplayName')
}
function Get-MDMMAMObject
{
param($object, $additional = "")
if(-not $Object.objectId) { return }
Invoke-AzureNativeRequest "/MdmApplications/$($Object.objectId)$additional"
}
function Export-AllMDMMAM
{
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-SingleMDMMAM $objTmp.Object $path
}
}
}
function Export-SelectedMDMMAM
{
param($path = "$env:Temp")
Export-SingleMDMMAM $global:dgObjects.SelectedItem.Object $path
}
function Export-SingleMDMMAM
{
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-MDMMAMFolderName) }
}
if(-not (Test-Path $path)) { mkdir -Path $path -Force -ErrorAction SilentlyContinue | Out-Null }
if(Test-Path $path)
{
Write-Status "Export $($psObj.appDisplayName)"
$obj = Invoke-AzureNativeRequest "MdmApplications/$($psObj.objectId)"
if($obj)
{
$fileName = "$path\$((Remove-InvalidFileNameChars $obj.appDisplayName)).json"
ConvertTo-Json $obj -Depth 5 | Out-File $fileName -Force
}
if($obj.mdmAppliesToGroups)
{
$obj.mdmAppliesToGroups | ForEach-Object { Add-GroupMigrationObject $PSItem.objectId }
}
if($obj.mamAppliesToGroups)
{
$obj.mamAppliesToGroups | ForEach-Object { Add-GroupMigrationObject $PSItem.objectId }
}
$global:exportedObjects++
}
}
function Import-MDMMAM
{
param($obj)
$argStr = "?"
if($obj.enrollmentUrl) { $argStr += "mdmAppliesToChanged=true" }
else{ $argStr += "mdmAppliesToChanged=false" }
if($obj.mamEnrollmentUrl) { $argStr += "&mamAppliesToChanged=true" }
else{ $argStr += "&mamAppliesToChanged=false" }
$response = Invoke-AzureNativeRequest "MdmApplications/$($obj.objectId)$argStr" -Method PUT -Body (Update-JsonForEnvironment (ConvertTo-Json $obj -Depth 5))
}
function Import-AllMDMMAMObjects
{
param($path = "$env:Temp")
Import-MDMMAMObjects (Get-JsonFileObjects $path)
}
function Import-MDMMAMObjects
{
param(
$Objects,
[switch]
$Selected
)
Write-Status "Import MDM/MAM settings"
foreach($obj in $objects)
{
if($Selected -and $obj.Selected -ne $true) { continue }
Write-Log "Import MDM/MAM app settings: $($obj.Object.appDisplayName)"
Import-MDMMAM $obj.Object
# No assignments for MDM/MAM
}
$dgObjects.ItemsSource = @(Get-MDMMAMObjects)
Write-Status ""
}

File diff suppressed because it is too large Load Diff

1952
Extensions/MSGraph.psm1 Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,314 +0,0 @@
########################################################
#
# Common module functions
#
########################################################
function Add-ModuleMenuItems
{
Add-MenuItem (New-Object PSObject -Property @{
Title = (Get-PowerShellScriptName)
MenuID = "IntuneGraphAPI"
Script = [ScriptBlock]{Get-PowerShellScripts}
})
}
function Get-SupportedImportObjects
{
$global:importObjects += (New-Object PSObject -Property @{
Selected = $true
Title = (Get-PowerShellScriptName)
Script = [ScriptBlock]{
param($rootFolder)
Write-Status "Import all powershell scripts"
Import-AllPowerShellScriptObjects (Join-Path $rootFolder (Get-PowerShellScriptFolderName))
}
})
}
function Get-SupportedExportObjects
{
$global:exportObjects += (New-Object PSObject -Property @{
Selected = $true
Title = (Get-PowerShellScriptName)
Script = [ScriptBlock]{
param($rootFolder)
Write-Status "Export all powershell scripts"
Get-PowerShellScriptObjects | ForEach-Object { Export-SinglePowerShellScript $PSItem.Object (Join-Path $rootFolder (Get-PowerShellScriptFolderName)) }
}
})
}
function Export-AllObjects
{
param($addObjectSubfolder)
$subFolder = ""
if($addObjectSubfolder) { $subFolder = Get-PowerShellScriptFolderName }
}
########################################################
#
# Object specific functions
#
########################################################
function Get-PowerShellScriptName
{
return "PowerShell Script"
}
function Get-PowerShellScriptFolderName
{
return "PowerShell"
}
function Get-PowerShellScripts
{
Write-Status "Loading PowerShell objects"
$dgObjects.ItemsSource = @(Get-PowerShellScriptObjects)
#Scriptblocks that will perform the export tasks. empty by default
$script:exportParams = @{}
$script:exportParams.Add("ExportAllScript", [ScriptBlock]{
Export-AllPowerShellScripts $global:txtExportPath.Text
Set-ObjectGrid
Write-Status ""
})
$script:exportParams.Add("ExportSelectedScript", [ScriptBlock]{
Export-SelectedPowerShellScript $global:txtExportPath.Text
Set-ObjectGrid
Write-Status ""
})
#Scriptblock that will perform the import all files
$script:importAll = [ScriptBlock]{
Import-AllPowerShellScriptObjects $global:txtImportPath.Text
Set-ObjectGrid
}
#Scriptblock that will perform the import of selected files
$script:importSelected = [ScriptBlock]{
Import-PowerShellScriptObjects $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")
}
$exportExtension = (New-Object PSObject -Property @{
Xaml = @"
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="TitleColumn" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal" Margin="0,0,5,0">
<Label Content="Export script" />
<Rectangle Style="{DynamicResource InfoIcon}" ToolTip="Export the powershell script to a ps1 file" />
</StackPanel>
<CheckBox Grid.Column='1' Name='chkExportScript' VerticalAlignment="Center" IsChecked="true" />
</Grid>
"@
Script = [ScriptBlock]{
param($form)
$script:chkExportScript = $form.FindName("chkExportScript")
}
})
$script:exportParams.Add("Extension", $exportExtension)
Add-DefaultObjectButtons -export ([scriptblock]{Show-DefaultExportGrid @script:exportParams}) -import ([scriptblock]{Show-DefaultImportGrid -ImportAll $script:importAll -ImportSelected $script:importSelected -GetFiles $script:getImportFiles}) -copy ([scriptblock]{Copy-PowerShellScript}) -ViewFullObject ([scriptblock]{Get-PowerShellScriptObject $global:dgObjects.SelectedItem.Object})
#Add download button
$btnDownload = New-Object System.Windows.Controls.Button
$btnDownload.Content = 'Download'
$btnDownload.Name = 'btnDownload'
$btnDownload.Margin = "5,0,0,0"
$btnDownload.Width = "100"
$spSubMenu.Children.Insert(0, $btnDownload)
$btnDownload.Add_Click({
Invoke-DownloadScript
})
}
function Get-PowerShellScriptObjects
{
Get-GraphObjects -Url "/deviceManagement/deviceManagementScripts"
}
function Get-PowerShellScriptObject
{
param($object, $additional = "")
if(-not $Object.id) { return }
Invoke-GraphRequest -Url "/deviceManagement/deviceManagementScripts/$($object.id)$additional"
}
function Export-AllPowerShellScripts
{
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-SinglePowerShellScript $objTmp.Object $path
}
}
}
function Export-SelectedPowerShellScript
{
param($path = "$env:Temp")
Export-SinglePowerShellScript $global:dgObjects.SelectedItem.Object $path
}
function Export-SinglePowerShellScript
{
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-PowerShellScriptFolderName) }
}
if(-not (Test-Path $path)) { mkdir -Path $path -Force -ErrorAction SilentlyContinue | Out-Null }
if(Test-Path $path)
{
Write-Status "Export $($psObj.displayName)"
$obj = Get-PowerShellScriptObject -object $psObj -additional "?`$expand=assignments"
#$obj = Invoke-GraphRequest -Url "/deviceManagement/deviceManagementScripts/$($psObj.id)?`$expand=assignments"
if($obj)
{
$fileName = "$path\$((Remove-InvalidFileNameChars $obj.displayName)).json"
ConvertTo-Json $obj -Depth 5 | Out-File $fileName -Force
if($script:chkExportScript.IsChecked)
{
$fileName = "$path\$($obj.FileName)"
[System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String($obj.scriptContent)) | Out-File $fileName -Force
}
Add-MigrationInfo $obj.assignments
$global:exportedObjects++
}
}
}
function Copy-PowerShellScript
{
if(-not $dgObjects.SelectedItem)
{
[System.Windows.MessageBox]::Show("No object selected`n`nSelect PowerShell script you want to copy", "Error", "OK", "Error")
return
}
$ret = Show-InputDialog "Copy PowerShell script" "Select name for the new object" "$($global:dgObjects.SelectedItem.displayName) - Copy"
if($ret)
{
# Export profile
Write-Status "Export $($dgObjects.SelectedItem.displayName)"
$obj = Get-PowerShellScriptObject -object $dgObjects.SelectedItem.Object
#$obj = Invoke-GraphRequest -Url "/deviceManagement/deviceManagementScripts/$($dgObjects.SelectedItem.id)"
if($obj)
{
# Import new profile
$obj.displayName = $ret
Import-PowerShellScript $obj | Out-null
$dgObjects.ItemsSource = @(Get-PowerShellScriptObjects)
}
Write-Status ""
}
$dgObjects.Focus()
}
function Import-PowerShellScript
{
param($obj)
Start-PreImport $obj -RemoveProperties @("id","assignments@odata.context","assignments")
Write-Status "Import $($obj.displayName)"
Invoke-GraphRequest -Url "/deviceManagement/deviceManagementScripts" -Content (ConvertTo-Json $obj -Depth 5) -HttpMethod POST
}
function Import-AllPowerShellScriptObjects
{
param(
$path = "$env:Temp"
)
Import-PowerShellScriptObjects (Get-JsonFileObjects $path)
}
function Import-PowerShellScriptObjects
{
param(
$Objects,
[switch]
$Selected
)
Write-Status "Import PowerShell scripts"
foreach($obj in $objects)
{
if($Selected -and $obj.Selected -ne $true) { continue }
Write-Log "Import PowerShell script: $($obj.Object.displayName)"
$assignments = Get-GraphAssignmentsObject $obj.Object ($obj.FileInfo.DirectoryName + "\" + $obj.FileInfo.BaseName + "_assignments.json")
$response = Import-PowerShellScript $obj.Object
if($response)
{
$global:importedObjects++
Import-GraphAssignments $assignments "deviceManagementScriptAssignments" "/deviceManagement/deviceManagementScripts/$($response.Id)/assign"
}
}
$dgObjects.ItemsSource = @(Get-PowerShellScriptObjects)
Write-Status ""
}
function Invoke-DownloadScript
{
if(-not $global:dgObjects.SelectedItem.Object.id) { return }
$obj = Get-PowerShellScriptObject -object $dgObjects.SelectedItem.Object
#$obj = Invoke-GraphRequest -Url "/deviceManagement/deviceManagementScripts/$($global:dgObjects.SelectedItem.Object.id)"
if($obj.scriptContent)
{
Write-Log "Download PowerShell script '$($obj.FileName)' from $($obj.displayName)"
$fileName = "$path\$($obj.FileName)"
$dlgSave = New-Object -Typename System.Windows.Forms.SaveFileDialog
$dlgSave.InitialDirectory = Get-SettingValue "IntuneRootFolder" $env:Temp
$dlgSave.FileName = $obj.FileName
if($dlgSave.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK -and $dlgSave.Filename)
{
[System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String($obj.scriptContent)) | Out-File $dlgSave.Filename -Force
}
}
}

View File

@@ -1,253 +0,0 @@
########################################################
#
# Common module functions
#
########################################################
function Add-ModuleMenuItems
{
Add-MenuItem (New-Object PSObject -Property @{
Title = (Get-TermsAndConditionName)
MenuID = "IntuneGraphAPI"
Script = [ScriptBlock]{Get-TermsAndConditions}
})
}
function Get-SupportedImportObjects
{
$global:importObjects += (New-Object PSObject -Property @{
Selected = $true
Title = (Get-TermsAndConditionName)
Script = [ScriptBlock]{
param($rootFolder)
Write-Status "Import all terms and conditions"
Import-AllTermsAndConditionObjects (Join-Path $rootFolder (Get-TermsAndConditionFolderName))
}
})
}
function Get-SupportedExportObjects
{
$global:exportObjects += (New-Object PSObject -Property @{
Selected = $true
Title = (Get-TermsAndConditionName)
Script = [ScriptBlock]{
param($rootFolder)
Write-Status "Export all Intune terms and conditions"
Get-TermsAndConditionObjects | ForEach-Object { Export-SingleTermsAndCondition $PSItem.Object (Join-Path $rootFolder (Get-TermsAndConditionFolderName)) }
}
})
}
function Export-AllObjects
{
param($addObjectSubfolder)
$subFolder = ""
if($addObjectSubfolder) { $subFolder = Get-TermsAndConditionFolderName }
}
########################################################
#
# Object specific functions
#
########################################################
function Get-TermsAndConditionName
{
return "Terms and Conditions"
}
function Get-TermsAndConditionFolderName
{
return "TermsAndConditions"
}
function Get-TermsAndConditions
{
Write-Status "Loading terms and conditions"
$dgObjects.ItemsSource = @(Get-TermsAndConditionObjects)
#Scriptblocks that will perform the export tasks. empty by default
$script:exportParams = @{}
$script:exportParams.Add("ExportAllScript", [ScriptBlock]{
Export-AllTermsAndConditions $global:txtExportPath.Text
Set-ObjectGrid
Write-Status ""
})
$script:exportParams.Add("ExportSelectedScript", [ScriptBlock]{
Export-SelectedTermsAndCondition $global:txtExportPath.Text
Set-ObjectGrid
Write-Status ""
})
#Scriptblock that will perform the import all files
$script:importAll = [ScriptBlock]{
Import-AllTermsAndConditionObjects $global:txtImportPath.Text
Set-ObjectGrid
}
#Scriptblock that will perform the import of selected files
$script:importSelected = [ScriptBlock]{
Import-TermsAndConditionObjects $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}) -copy ([scriptblock]{Copy-TermsAndCondition}) -ViewFullObject ([scriptblock]{Get-TermsAndConditionObject $global:dgObjects.SelectedItem.Object})
}
function Get-TermsAndConditionObjects
{
Get-GraphObjects -Url "/deviceManagement/termsAndConditions"
}
function Get-TermsAndConditionObject
{
param($object, $additional = "")
if(-not $Object.id) { return }
Invoke-GraphRequest -Url "/deviceManagement/termsAndConditions/$($Object.id)$additional"
}
function Export-AllTermsAndConditions
{
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-SingleTermsAndCondition $objTmp.Object $path
}
}
}
function Export-SelectedTermsAndCondition
{
param($path = "$env:Temp")
Export-SingleTermsAndCondition $global:dgObjects.SelectedItem.Object $path
}
function Export-SingleTermsAndCondition
{
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-TermsAndConditionFolderName) }
}
if(-not (Test-Path $path)) { mkdir -Path $path -Force -ErrorAction SilentlyContinue | Out-Null }
if(Test-Path $path)
{
Write-Status "Export $($psObj.displayName)"
$obj = Invoke-GraphRequest -Url "/deviceManagement/termsAndConditions/$($psObj.id)" #?`$expand=assignments"
if($obj)
{
# ?`$expand=assignments is not working so get assignments
$assignments = Invoke-GraphRequest -Url "/deviceManagement/termsAndConditions/$($obj.id)/assignments"
if($assignments.value)
{
$obj | Add-Member -NotePropertyName "assignments" -NotePropertyValue $assignments.value
}
$fileName = "$path\$((Remove-InvalidFileNameChars $obj.displayName)).json"
ConvertTo-Json $obj -Depth 5 | Out-File $fileName -Force
Add-MigrationInfo $obj.assignments
}
$global:exportedObjects++
}
}
function Copy-TermsAndCondition
{
if(-not $dgObjects.SelectedItem)
{
[System.Windows.MessageBox]::Show("No object selected`n`nSelect terms and conditions item you want to copy", "Error", "OK", "Error")
return
}
$ret = Show-InputDialog "Copy terms and conditions" "Select name for the new object" "$($dgObjects.SelectedItem.displayName) - Copy"
if($ret)
{
# Export profile
Write-Status "Export $($dgObjects.SelectedItem.displayName)"
# Get full object for export
$obj = Invoke-GraphRequest -Url "/deviceManagement/termsAndConditions/$($dgObjects.SelectedItem.Object.id)"
if($obj)
{
# Import new profile
$obj.displayName = $ret
Import-TermsAndCondition $obj | Out-Null
$dgObjects.ItemsSource = @(Get-TermsAndConditionObjects)
}
Write-Status ""
}
$dgObjects.Focus()
}
function Import-TermsAndCondition
{
param($obj)
Write-Status "Import $($obj.displayName)"
Start-PreImport $obj
Invoke-GraphRequest -Url "/deviceManagement/termsAndConditions" -Content (ConvertTo-Json $obj -Depth 5) -HttpMethod POST
}
function Import-AllTermsAndConditionObjects
{
param($path = "$env:Temp")
Import-TermsAndConditionObjects (Get-JsonFileObjects $path)
}
function Import-TermsAndConditionObjects
{
param(
$Objects,
[switch]
$Selected
)
Write-Status "Import terms and conditions"
foreach($obj in $objects)
{
if($Selected -and $obj.Selected -ne $true) { continue }
Write-Log "Import Terms and Conditions: $($obj.Object.displayName)"
$assignments = Get-GraphAssignmentsObject $obj.Object ($obj.FileInfo.DirectoryName + "\" + $obj.FileInfo.BaseName + "_assignments.json")
$response = Import-TermsAndCondition $obj.Object
if($response)
{
$global:importedObjects++
Import-GraphAssignments2 $assignments "/deviceManagement/termsAndConditions/$($response.Id)/assignments"
}
}
$dgObjects.ItemsSource = @(Get-TermsAndConditionObjects)
Write-Status ""
}