This commit is contained in:
Mikael Karlsson
2021-08-15 20:54:37 +10:00
parent d3a3ddef79
commit 95bd8fc07c
229 changed files with 12061 additions and 6028 deletions

View File

@@ -11,7 +11,7 @@ Objects can be compared based on Properties or Documentatation info.
function Get-ModuleVersion
{
'1.0.5'
'1.0.6'
}
function Invoke-InitializeModule
@@ -160,6 +160,9 @@ function Show-CompareBulkForm
$global:cbCompareType.ItemsSource = $global:comparisonTypes | Where ShowOnBulk -ne $false
$global:cbCompareType.SelectedValue = (Get-Setting "Compare" "Type" "property")
$global:cbCompareCSVDelimiter.ItemsSource = @("", ",",";","-","|")
$global:cbCompareCSVDelimiter.SelectedValue = (Get-Setting "Compare" "Delimiter" ";")
$script:compareObjects = @()
foreach($objType in $global:lstMenuItems.ItemsSource)
{
@@ -202,8 +205,9 @@ function Show-CompareBulkForm
Add-XamlEvent $script:form "btnStartCompare" "add_click" {
Write-Status "Compare objects"
Save-Setting "Compare" "Provider" $global:cbCompareProvider.SelectedValue
Save-Setting "Compare" "Type" $global:cbCompareType.SelectedValue
Save-Setting "Compare" "Provider" $global:cbCompareProvider.SelectedValue
Save-Setting "Compare" "Type" $global:cbCompareType.SelectedValue
Save-Setting "Compare" "Delimiter" $global:cbCompareCSVDelimiter.SelectedValue
if($global:cbCompareProvider.SelectedItem.BulkCompare)
{
& $global:cbCompareProvider.SelectedItem.BulkCompare
@@ -530,7 +534,8 @@ function Start-BulkCompareExportObjects
}
else
{
$sourceObj = Get-GraphObject $curObject.Object $curObject.ObjectType
$sourceObj = Get-GraphObject $curObject.Object $curObject.ObjectType
$fileObj.Object | Add-Member Noteproperty -Name "@ObjectFromFile" -Value $true -Force
$compareProperties = Compare-Objects $sourceObj.Object $fileObj.Object $item.ObjectType
}
@@ -618,8 +623,20 @@ function Save-BulkCompareResults
if($compResultValues.Count -gt 0)
{
$params = @{}
try
{
if($global:cbCompareCSVDelimiter.Text)
{
$params.Add("Delimiter", [char]$global:cbCompareCSVDelimiter.Text)
}
}
catch
{
}
Write-Log "Save bulk comare results to $file"
$compResultValues | Select -Property $props | ConvertTo-Csv -NoTypeInformation | Out-File -LiteralPath $file -Force -Encoding UTF8
$compResultValues | Select -Property $props | ConvertTo-Csv -NoTypeInformation @params | Out-File -LiteralPath $file -Force -Encoding UTF8
}
}
@@ -798,6 +815,8 @@ function Start-CompareExportObject
}
}
$compareObj | Add-Member Noteproperty -Name "@ObjectFromFile" -Value $true -Force
$compareResult = Compare-Objects $obj.Object $compareObj $obj.ObjectType
$global:dgCompareInfo.ItemsSource = $compareResult
@@ -817,16 +836,6 @@ function Compare-Objects
{
Write-Log "Selected comparison type ($($global:cbCompareType.SelectedItem.Name)) does not have a Compare property specified" 3
}
<#
elseif($global:cbCompareType.SelectedValue -eq "property")
{
$compareResult = Compare-ObjectsBasedonProperty $obj1 $obj2 $objectType
}
elseif($global:cbCompareType.SelectedValue -eq "doc")
{
$compareResult = Compare-ObjectsBasedonDocumentation $obj1 $obj2 $objectType
}
#>
$compareResult
}
@@ -854,10 +863,6 @@ function Add-CompareProperty
$value1 = if($value1 -eq $null) { "" } else { $value1.ToString().Trim("`"") }
$value2 = if($value2 -eq $null) { "" } else { $value2.ToString().Trim("`"") }
if( ($value1 -eq $value2) -eq $false)
{
$dummy = 1
}
$script:compareProperties += [PSCustomObject]@{
PropertyName = $name
@@ -962,7 +967,6 @@ function Compare-ObjectsBasedonDocumentation
ObjectType = $objectType
})
$obj2 | Add-Member Noteproperty -Name "@ObjectFromFile" -Value $true -Force
$docObj2 = Invoke-ObjectDocumentation ([PSCustomObject]@{
Object = $obj2
@@ -1049,7 +1053,7 @@ function Compare-ObjectsBasedonDocumentation
$addedProperties += ($prop.EntityKey + $prop.Category + $prop.SubCategory)
$val1 = $prop.$settingsValue
$prop2 = $docObj2.Settings | Where { $_.EntityKey -eq $prop.EntityKey -and $_.Category -eq $prop.Category -and $_.SubCategory -eq $prop.SubCategory }
$prop2 = $docObj2.Settings | Where { $_.EntityKey -eq $prop.EntityKey -and $_.Category -eq $prop.Category -and $_.SubCategory -eq $prop.SubCategory -and $_.Enabled -eq $prop.Enabled }
$val2 = $prop2.$settingsValue
Add-CompareProperty $prop.Name $val1 $val2 $prop.Category $prop.SubCategory
}
@@ -1061,7 +1065,7 @@ function Compare-ObjectsBasedonDocumentation
$addedProperties += ($prop.EntityKey + $prop.Category + $prop.SubCategory)
$val2 = $prop.$settingsValue
$prop2 = $docObj1.Settings | Where { $_.EntityKey -eq $prop.EntityKey -and $_.Category -eq $prop.Category -and $_.SubCategory -eq $prop.SubCategory }
$prop2 = $docObj1.Settings | Where { $_.EntityKey -eq $prop.EntityKey -and $_.Category -eq $prop.Category -and $_.SubCategory -eq $prop.SubCategory -and $_.Enabled -eq $prop.Enabled }
$val1 = $prop2.$settingsValue
Add-CompareProperty $prop.Name $val1 $val2 $prop.Category $prop.SubCategory
}

View File

@@ -20,7 +20,7 @@ $global:documentationProviders = @()
function Get-ModuleVersion
{
'1.0.5'
'1.0.6'
}
function Invoke-InitializeModule
@@ -283,7 +283,8 @@ function Get-ObjectDocumentation
DefaultDocumentationProperties = $defaultDocumentationProperties
ErrorText = $status
InputType = $inputType
UpdateFilteredObject = $updateFilteredObject
UpdateFilteredObject = $updateFilteredObject
UnconfiguredProperties = $obj."@UnconfiguredProperties"
}
}
@@ -1175,6 +1176,7 @@ function Get-IntentSettingInfo
; # Skip child settings
}
elseif($valueObj.'@odata.type' -eq '#microsoft.graph.deviceManagementCollectionSettingInstance' -or
$defObj.'@odata.type' -eq '#microsoft.graph.deviceManagementComplexSettingDefinition' -or
$defObj."valueType" -eq "collection")
{
$valueArr = @()
@@ -1231,9 +1233,10 @@ function Get-IntentSettingInfo
}
$valueSet = $valueArr.Count -gt 0
}
elseif($valueObj.'@odata.type' -eq '#microsoft.graph.deviceManagementAbstractComplexSettingInstance')
elseif($valueObj.'@odata.type' -eq '#microsoft.graph.deviceManagementAbstractComplexSettingInstance' -or
$defObj.'@odata.type' -eq '#microsoft.graph.deviceManagementAbstractComplexSettingDefinition')
{
$tmpDef = $category.settingDefinitions | Where id -eq $rawValue.'$implementationId'
$tmpDef = $category.settingDefinitions | Where id -eq $rawValue.implementationId
if($tmpDef)
{
$itemValue = $tmpDef.displayName
@@ -1284,7 +1287,8 @@ function Get-IntentSettingInfo
{
; # Skip children if value is not set...
}
elseif($valueObj.'@odata.type' -eq '#microsoft.graph.deviceManagementComplexSettingInstance')
elseif($valueObj.'@odata.type' -eq '#microsoft.graph.deviceManagementComplexSettingInstance' -or
$defObj.'@odata.type' -eq '#microsoft.graph.deviceManagementComplexSettingDefinition')
{
if($valueObj.Value)
{
@@ -1373,7 +1377,9 @@ function Get-IntentSettingInfo
$curObjectInfo.Value = ?: $isValueSet "Configure" (Get-LanguageString "SettingDetails.notConfigured")
$curObjectInfo.ValueSet = $isValueSet
}
elseif($valueObj.'@odata.type' -eq '#microsoft.graph.deviceManagementAbstractComplexSettingInstance' -and $rawValue -and $tmpDef )
elseif(($valueObj.'@odata.type' -eq '#microsoft.graph.deviceManagementAbstractComplexSettingInstance' -or
$defObj.'@odata.type' -eq '#microsoft.graph.deviceManagementAbstractComplexSettingDefinition') -and
$rawValue -and $tmpDef)
{
foreach($childDefId in $tmpDef.propertyDefinitionIds)
{
@@ -1675,7 +1681,7 @@ function Invoke-TranslateSection
}
elseif($tmpStr)
{
Write-Log "SubCategpry ignored based on length: $tmpStr" 2
Write-LogDebug "SubCategpry ignored based on length: $tmpStr" 2
}
}
Invoke-ChildSections $obj $prop
@@ -1741,6 +1747,7 @@ function Invoke-TranslateSection
if($rawValue -eq $null -and ![String]::IsNullOrEmpty($prop.unconfiguredValue) -and $global:chkSetUnconfiguredValue.IsChecked)
{
$propValue = $prop.unconfiguredValue
Add-NotConfiguredProperty $prop
}
elseif($rawValue -eq $null -and ![String]::IsNullOrEmpty($prop.defaultValue) -and $global:chkSetDefaultValue.IsChecked)
{
@@ -2366,10 +2373,24 @@ function Invoke-TranslateBoolean
}
else
{
Add-NotConfiguredProperty $prop
Get-LanguageString "BooleanActions.notConfigured"
}
}
function Add-NotConfiguredProperty
{
param($prop)
# Add not configured prop to the base object
if(-not ($script:currentObject.PSObject.Properties | Where Name -eq "@UnconfiguredProperties"))
{
$script:currentObject | Add-Member Noteproperty -Name "@UnconfiguredProperties" -Value @() -Force
}
$script:currentObject.'@UnconfiguredProperties' += $prop
}
function Invoke-TranslateOption
{
param($obj, $prop, [Switch]$SkipOptionChildren, $propValue = $null)
@@ -2398,6 +2419,11 @@ function Invoke-TranslateOption
}
elseif($option.nameResourceKey)
{
if($option.nameResourceKey -eq "notConfigured")
{
Add-NotConfiguredProperty $prop
}
$optionValue = (Get-LanguageString (?: $option.nameResourceKey.Contains(".") $option.nameResourceKey "SettingDetails.$($option.nameResourceKey)"))
}
else
@@ -2477,6 +2503,7 @@ function Invoke-TranslateMultiOption
}
else
{
Add-NotConfiguredProperty $prop
Get-LanguageString "BooleanActions.notConfigured"
}
}
@@ -2841,6 +2868,10 @@ function Invoke-TranslateAssignments
if($assignment.target.GroupId)
{
$groupName = ($groupInfo | Where id -eq $assignment.target.GroupId).displayName
if(-not $groupName)
{
$groupName = $assignment.target.GroupId
}
}
elseif($assignment.target.'@odata.type' -eq "#microsoft.graph.allDevicesAssignmentTarget")
{
@@ -3386,10 +3417,11 @@ function Show-DocumentationForm
Add-RawDataInfo $obj.Object $obj.ObjectType
$updateNotConfigured = $true
$notConfiguredLoc = Get-LanguageString "BooleanActions.notConfigured"
$notConfiguredText = ""
if($global:cbNotConifugredText.SelectedValue -eq "notConfigured")
{
$notConfiguredText = Get-LanguageString "BooleanActions.notConfigured"
$notConfiguredText = $notConfiguredLoc
}
elseif($global:cbNotConifugredText.SelectedValue -eq "asis")
{
@@ -3409,9 +3441,14 @@ function Show-DocumentationForm
break
}
if($global:chkSkipNotConfigured.IsChecked -and (([String]::IsNullOrEmpty($item.RawValue) -or $item.RawValue -eq "notConfigured")))
if($global:chkSkipNotConfigured.IsChecked -and (([String]::IsNullOrEmpty($item.RawValue) -or ("$($item.RawValue)" -eq "notConfigured"))))
{
# Skip unconfigured items
# Skip unconfigured items e.g. properties with null values
continue
}
elseif($global:chkSkipNotConfigured.IsChecked -and $documentedObj.UnconfiguredProperties -and ($documentedObj.UnconfiguredProperties | Where EntityKey -eq $item.EntityKey))
{
# Skip unconfigured items e.g. boolean with a value but Not Configured
continue
}
@@ -3438,7 +3475,14 @@ function Show-DocumentationForm
if($updateNotConfigured -and ($item.RawValue -eq $null -or "$($item.RawValue)" -eq "" -or "$($item.RawValue)" -eq "notConfigured") -and [String]::IsNullOrEmpty($item.Value))
{
$item.Value = $notConfiguredText
}
}
if($global:chkSkipNotConfigured.IsChecked -and $item.Value -eq $notConfiguredLoc)
{
# Skip unconfigured items based on value e.g. value = Not Configured
Write-Log "Skipping property $($itenm.Name) based on '$($notConfiguredLoc)' string value" 2
continue
}
$filteredSettings += $item
}
@@ -3577,6 +3621,13 @@ function Add-CSVOptionsControl
$global:spCSVCustomProperties.Visibility = (?: ($global:cbCSVDocumentationProperties.SelectedValue -ne "custom") "Collapsed" "Visible")
$global:txtCSVCustomProperties.Visibility = (?: ($global:cbCSVDocumentationProperties.SelectedValue -ne "custom") "Collapsed" "Visible")
$global:cbCSVDelimiter.ItemsSource = @("", ",",";","-","|")
try
{
$global:cbCSVDelimiter.SelectedIndex = $global:cbCSVDelimiter.ItemsSource.IndexOf((Get-Setting "Documentation" "CSVDelimiter"))
}
catch {}
Add-XamlEvent $script:csvForm "browseCSVDocumentationPath" "add_click" {
$folder = Get-Folder (Get-XamlProperty $script:csvForm "txtCSVDocumentationPath" "Text") "Select root folder for export"
if($folder)
@@ -3603,6 +3654,7 @@ function Invoke-CSVPreProcessItems
{
Save-Setting "Documentation" "CSVExportProperties" $global:cbCSVDocumentationProperties.SelectedValue
Save-Setting "Documentation" "CSVCustomDisplayProperties" $global:txtCSVCustomProperties.Text
Save-Setting "Documentation" "CSVDelimiter" $global:cbCSVDelimiter.Text
}
function Invoke-CSVProcessItem
@@ -3630,6 +3682,12 @@ function Invoke-CSVProcessItem
$itemsToExport = @()
$params = @{}
if($global:cbCSVDelimiter.Text)
{
$params.Add('Delimiter',$global:cbCSVDelimiter.Text)
}
if(($global:cbCSVDocumentationProperties.SelectedValue -eq 'extended' -and $documentedObj.DisplayProperties) -or
($global:cbCSVDocumentationProperties.SelectedValue -eq 'custom' -and $global:txtCSVCustomProperties.Text))
{
@@ -3687,14 +3745,14 @@ function Invoke-CSVProcessItem
$itemsToExport += ""
$itemsToExport += "# Assignments"
$itemsToExport += ""
$itemsToExport += $documentedObj.Assignments | Select $properties | ConvertTo-Csv -NoTypeInformation
$itemsToExport += $documentedObj.Assignments | Select $properties | ConvertTo-Csv -NoTypeInformation @params
}
}
else
{
$itemsToExport += $documentedObj.BasicInfo
$itemsToExport += $documentedObj.FilteredSettings
$itemsToExport = $itemsToExport | Select Name,Value | ConvertTo-Csv -NoTypeInformation
$itemsToExport = $itemsToExport | Select Name,Value | ConvertTo-Csv -NoTypeInformation @params
}
$fileName = $folder + "\$((Remove-InvalidFileNameChars $objName)).csv"

View File

@@ -10,7 +10,7 @@ This module will also document some objects based on PowerShell functions
function Get-ModuleVersion
{
'1.0.3'
'1.0.4'
}
function Invoke-InitializeModule
@@ -295,7 +295,7 @@ function Add-CDDocumentCustomProfileValue
return $false
}
}
elseif($topObj.'@OData.Type' -like "#microsoft.graph.windows10EndpointProtectionConfiguration")
elseif($topObj.'@OData.Type' -like "#microsoft.graph.windowsHealthMonitoringConfiguration")
{
if($prop.EntityKey -eq "configDeviceHealthMonitoringScope")
{
@@ -713,14 +713,13 @@ function Add-CDDocumentCustomProfileProperty
Add-DefenderFirewallSettings $obj.firewallProfilePrivate "Private"
Add-DefenderFirewallSettings $obj.firewallProfilePublic "Public"
$obj | Add-Member Noteproperty -Name "bitLockerBaseConfigureEncryptionMethods" -Value ($obj.bitLockerSystemDrivePolicy.encryptionMethod -ne $null) -Force
$obj | Add-Member Noteproperty -Name "bitLockerBaseConfigureEncryptionMethods" -Value (?: ($obj.bitLockerSystemDrivePolicy.encryptionMethod -ne $null) $true $null) -Force
$obj | Add-Member Noteproperty -Name "bitLockerSystemDriveEncryptionMethod" -Value $obj.bitLockerSystemDrivePolicy.encryptionMethod -Force
$obj | Add-Member Noteproperty -Name "bitLockerFixedDriveEncryptionMethod" -Value $obj.bitLockerFixedDrivePolicy.encryptionMethod -Force
$obj | Add-Member Noteproperty -Name "bitLockerRemovableDriveEncryptionMethod" -Value $obj.bitLockerRemovableDrivePolicy.encryptionMethod -Force
#$obj.bitLockerSystemDrivePolicy | Add-Member Noteproperty -Name "bitLockerMinimumPinLength" -Value ($obj.bitLockerSystemDrivePolicy.minimumPinLength -ne $null) -Force
$obj.bitLockerSystemDrivePolicy | Add-Member Noteproperty -Name "bitLockerMinimumPinLength" -Value ($obj.bitLockerSystemDrivePolicy.minimumPinLength -ne $null) -Force
$obj.bitLockerSystemDrivePolicy | Add-Member Noteproperty -Name "bitLockerSyntheticSystemDrivePolicybitLockerDriveRecovery" -Value ($obj.bitLockerSystemDrivePolicy.recoveryOptions -ne $null) -Force
$obj.bitLockerSystemDrivePolicy | Add-Member Noteproperty -Name "bitLockerMinimumPinLength" -Value (?: ($obj.bitLockerSystemDrivePolicy.minimumPinLength -ne $null) $true $null) -Force
$obj.bitLockerSystemDrivePolicy | Add-Member Noteproperty -Name "bitLockerSyntheticSystemDrivePolicybitLockerDriveRecovery" -Value (?: ($obj.bitLockerSystemDrivePolicy.recoveryOptions -ne $null) $true $null) -Force
if($obj.bitLockerSystemDrivePolicy.prebootRecoveryUrl -eq $null -and $obj.bitLockerSystemDrivePolicy.prebootRecoveryEnableMessageAndUrl -eq $null)
{
@@ -746,7 +745,7 @@ function Add-CDDocumentCustomProfileProperty
$obj.bitLockerSystemDrivePolicy | Add-Member Noteproperty -Name "bitLockerSyntheticSystemDrivePolicy$($tmpProp)" -Value $obj.bitLockerSystemDrivePolicy.recoveryOptions.$tmpProp -Force
}
$obj.bitLockerFixedDrivePolicy | Add-Member Noteproperty -Name "bitLockerSyntheticFixedDrivePolicybitLockerDriveRecovery" -Value ($obj.bitLockerFixedDrivePolicy.recoveryOptions -ne $null) -Force
$obj.bitLockerFixedDrivePolicy | Add-Member Noteproperty -Name "bitLockerSyntheticFixedDrivePolicybitLockerDriveRecovery" -Value (?: ($obj.bitLockerFixedDrivePolicy.recoveryOptions -ne $null) $true $null) -Force
foreach($tmpProp in ($obj.bitLockerFixedDrivePolicy.recoveryOptions.PSObject.Properties).Name)
{
@@ -2194,15 +2193,17 @@ function Invoke-CDDocumentCustomOMAUri
foreach($setting in $obj.omaSettings)
{
Add-CustomSettingObject ([PSCustomObject]@{
Name = (Get-LanguageString "TableHeaders.name")
# Add the name of the OMA-URI setting
Add-CustomSettingObject ([PSCustomObject]@{
Name = (Get-LanguageString "SettingDetails.nameName")
Value = $setting.displayName
EntityKey = "displayName_$($setting.omaUri)"
Category = $category
SubCategory = $setting.displayName
})
Add-CustomSettingObject ([PSCustomObject]@{
# Add the description of the OMA-URI setting
Add-CustomSettingObject ([PSCustomObject]@{
Name = (Get-LanguageString "TableHeaders.description")
Value = $setting.description
EntityKey = "description_$($setting.omaUri)"
@@ -2210,7 +2211,8 @@ function Invoke-CDDocumentCustomOMAUri
SubCategory = $setting.displayName
})
Add-CustomSettingObject ([PSCustomObject]@{
# Add the OMA-URI path of the OMA-URI setting
Add-CustomSettingObject ([PSCustomObject]@{
Name = (Get-LanguageString "SettingDetails.oMAURIName")
Value = $setting.omaUri
EntityKey = "omaUri_$($setting.omaUri)"
@@ -2253,6 +2255,7 @@ function Invoke-CDDocumentCustomOMAUri
if($value)
{
# Add the type of the OMA-URI setting
Add-CustomSettingObject ([PSCustomObject]@{
Name = (Get-LanguageString "SettingDetails.dataTypeName")
Value = $value
@@ -2262,15 +2265,40 @@ function Invoke-CDDocumentCustomOMAUri
})
}
$value = $setting.value
# Add the type of the OMA-URI setting
if($setting.isEncrypted -ne $true)
{
if($setting.'@OData.Type' -eq '#microsoft.graph.omaSettingStringXml')
{
$value = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($value))
}
Add-CustomSettingObject ([PSCustomObject]@{
Name = (Get-LanguageString "SettingDetails.valueName")
Value = $setting.value
Value = $value
EntityKey = "value_$($setting.omaUri)"
Category = $category
SubCategory = $setting.displayName
})
}
else # ToDo: Add check button
{
if($obj.'@ObjectFromFile' -ne $true)
{
$xmlValue = Invoke-GraphRequest -Url "/deviceManagement/deviceConfigurations/$($obj.Id)/getOmaSettingPlainTextValue(secretReferenceValueId='$($setting.secretReferenceValueId)')"
$value = $xmlValue.Value
if($value)
{
Add-CustomSettingObject ([PSCustomObject]@{
Name = (Get-LanguageString "SettingDetails.valueName")
Value = $value
EntityKey = "value_$($setting.omaUri)"
Category = $category
SubCategory = $setting.displayName
})
}
}
}
}
}

View File

@@ -3,7 +3,7 @@
#https://docs.microsoft.com/en-us/office/vba/api/overview/word
function Get-ModuleVersion
{
'1.0.2'
'1.0.3'
}
function Invoke-InitializeModule
@@ -54,9 +54,7 @@ function Invoke-InitializeModule
CombinedValueWithLabel="TableHeaders.value"
CombinedValue="TableHeaders.value"
useDeviceLicensing="TableHeaders.licenseType"
#filterMode="Filter mode" # Not in any sring file yet
#filterMode="Filter mode" # Not in any string file yet
}
}
@@ -83,6 +81,10 @@ function Add-WordOptionsControl
$global:txtWordTableHeaderStyle.Text = Get-Setting "Documentation" "WordTableHeaderStyle" ""
$global:txtWordCategoryHeaderStyle.Text = Get-Setting "Documentation" "WordCategoryHeaderStyle" ""
$global:txtWordSubCategoryHeaderStyle.Text = Get-Setting "Documentation" "WordSubCategoryHeaderStyle" ""
$global:txtWordContentControls.Text = Get-Setting "Documentation" "WordContentControls" "Year=;Address="
$global:txtWordTitleProperty.Text = Get-Setting "Documentation" "WordTitleProperty" "Intune documentation"
$global:txtWordSubjectProperty.Text = Get-Setting "Documentation" "WordSubjectProperty" "Intune documentation"
$global:chkWordOpenDocument.IsChecked = ((Get-Setting "Documentation" "WordOpenDocument" "true") -ne "false")
@@ -125,6 +127,9 @@ function Invoke-WordPreProcessItems
Save-Setting "Documentation" "WordTableHeaderStyle" $global:txtWordTableHeaderStyle.Text
Save-Setting "Documentation" "WordCategoryHeaderStyle" $global:txtWordCategoryHeaderStyle.Text
Save-Setting "Documentation" "WordSubCategoryHeaderStyle" $global:txtWordSubCategoryHeaderStyle.Text
Save-Setting "Documentation" "WordContentControls" $global:txtWordContentControls.Text
Save-Setting "Documentation" "WordTitleProperty" $global:txtWordTitleProperty.Text
Save-Setting "Documentation" "WordSubjectProperty" $global:txtWordSubjectProperty.Text
try
{
@@ -205,6 +210,69 @@ function Invoke-WordPreProcessItems
}
$script:builtinStyles = [Enum]::GetNames([Microsoft.Office.Interop.Word.wdBuiltinStyle])
if(-not $global:txtWordDocumentTemplate.Text)
{
$script:doc.Application.Templates.LoadBuildingBlocks()
$BuildingBlocks = $script:doc.Application.Templates | Where {$_.name -eq 'Built-In Building Blocks.dotx'}
if($BuildingBlocks)
{
$coverPageName = ?? $global:txtWordCoverPage.Text 'Ion (Dark)'
try
{
$blocks = @()
for($i = 1;$i -le $BuildingBlocks.BuildingBlockEntries.Count;$i++)
{
$blocks += $BuildingBlocks.BuildingBlockEntries.Item($i)
}
$coverPages = (($blocks | Where { $_.Type.Index -eq 2 } | Select Name) | Sort -Property Name).Name
if(($coverPages | measure).Count -gt 0)
{
if($coverPageName -notin $coverPages)
{
Write-Log "$coverPageName not found in available Cover Page list. Using: $($coverPages[0])"
Write-Log "Available Cover Pages: $(($coverPages -join ","))"
$coverPageName = $coverPages[0]
}
else
{
Write-Log "Add Cover Page: $coverPageName"
}
}
$coverPage = $BuildingBlocks.BuildingBlockEntries.Item($coverPageName)
$coverPage.Insert($script:wordApp.Selection.Range,$true) | Out-Null
$script:wordApp.Selection.InsertNewPage()
}
catch
{
Write-LogError "Failed to create Cover Page" $_.Exception
}
try
{
$coverPageProps = $script:doc.CustomXMLParts | where { $_.NamespaceURI -match "coverPageProps$" }
if($coverPageProps)
{
Write-Log "Available Cover Page properties for $($coverPageName): $(((([xml]$coverPageProps.DocumentElement.XML).ChildNodes[0].ChildNodes).Name -join ","))"
}
}
catch{}
try
{
$script:doc.TablesOfContents.Add($script:wordApp.Selection.Range) | out-null
$script:wordApp.Selection.InsertNewPage()
}
catch
{
Write-LogError "Failed to create Table of Contents" $_.Exception
}
}
}
}
function Invoke-WordPostProcessItems
@@ -216,17 +284,34 @@ function Invoke-WordPostProcessItems
}
#Add properties - ToDo: This is static...
Set-WordDocBuiltInProperty "wdPropertyTitle" "Intune documentation"
Set-WordDocBuiltInProperty "wdPropertySubject" "Intune documentation"
Set-WordDocBuiltInProperty "wdPropertyTitle" (?? $global:txtWordTitleProperty.Text "Intune documentation")
Set-WordDocBuiltInProperty "wdPropertySubject" (?? $global:txtWordSubjectProperty.Text "Intune documentation")
Set-WordDocBuiltInProperty "wdPropertyAuthor" $userName
Set-WordDocBuiltInProperty "wdPropertyCompany" $global:Organization.displayName
Set-WordDocBuiltInProperty "wdPropertyKeywords" "Intune,Endpoint Manager,MEM"
try
{
# ToDo: Add support for custom properties
# Add: https://docs.microsoft.com/en-us/dotnet/api/microsoft.office.core.documentproperties.add?view=office-pia
# Types: https://docs.microsoft.com/en-us/dotnet/api/microsoft.office.core.msodocproperties?view=office-pia
#$coverPageProps = $script:doc.CustomXMLParts | where { $_.NamespaceURI -match "coverPageProps$" }
#[System.__ComObject].InvokeMember("add",[System.Reflection.BindingFlags]::InvokeMethod,$null,$script:doc.CustomDocumentProperties,([array]("PropName", $false, 4, "PropValue")))
$ContentControlProperties = $global:txtWordContentControls.Text #"Year=;Address=TestAddress"
foreach($ccObj in $ContentControlProperties.Split(';'))
{
$ccName,$ccVal = $ccObj.Split('=')
Set-WordContentControlText $ccName $ccVal
}
}
catch {}
#update fields, ToC etc.
$script:doc.Fields | ForEach-Object -Process { $_.Update() | Out-Null }
$script:doc.TablesOfContents | ForEach-Object -Process { $_.Update() | Out-Null }
$script:doc.TablesOfFigures | ForEach-Object -Process { $_.Update() | Out-Null }
$script:doc.TablesOfFigures | ForEach-Object -Process { $_.Update() | Out-Null }
$script:doc.TablesOfAuthorities | ForEach-Object -Process { $_.Update() | Out-Null }
$fileName = $global:txtWordDocumentName.Text
if(-not $fileName)
@@ -250,15 +335,57 @@ function Invoke-WordPostProcessItems
if($global:chkWordOpenDocument.IsChecked -eq $true)
{
$wordApp.Visible = $true
$wordApp.WindowState = [Microsoft.Office.Interop.Word.WdWindowState]::wdWindowStateMaximize
$wordApp.Activate()
[Console.Window]::SetForegroundWindow($wordApp.ActiveWindow.Hwnd) | Out-Null
$script:wordApp.Visible = $true
$script:wordApp.WindowState = [Microsoft.Office.Interop.Word.WdWindowState]::wdWindowStateMaximize
$script:wordApp.Activate()
[Console.Window]::SetForegroundWindow($script:wordApp.ActiveWindow.Hwnd) | Out-Null
}
else
{
$script:doc.Close([Microsoft.Office.Interop.Word.WdSaveOptions]::wdDoNotSaveChanges)
$wordApp.Quit()
$script:wordApp.Quit()
}
}
function Set-WordContentControlText
{
param($controlName, $value)
if(-not $controlName) { return }
try
{
$ctrl = $script:doc.SelectContentControlsByTitle($controlName)
if($ctrl)
{
Write-LogDebug "Update ContentControl $controlName (Type: $($ctrl[1].Type))"
if($ctrl[1].Type -eq 6)
{
if($ctrl[1].DateDisplayFormat)
{
$ctrl[1].Range.Text = (Get-Date).ToString($ctrl[1].DateDisplayFormat)
}
else
{
$ctrl[1].Range.Text = (Get-Date).ToShortDateString()
}
}
else
{
if(-not $value) { return }
$ctrl[1].Range.Text = $value
}
}
else
{
Write-Log "No ContentControl found with name $controlName" 2
}
}
catch
{
Write-LogError "Failed to set ContentControl $controlName" $_.Exception
}
}

View File

@@ -10,7 +10,7 @@ This module is for the Endpoint Manager/Intune View. It manages Export/Import/Co
#>
function Get-ModuleVersion
{
'3.1.8'
'3.1.9'
}
function Invoke-InitializeModule
@@ -106,7 +106,9 @@ function Invoke-InitializeModule
Permissons=@("DeviceManagementConfiguration.ReadWrite.All")
PropertiesToRemove = @("privacyAccessControls")
PostFileImportCommand = { Start-PostFileImportDeviceConfiguration @args }
PreCopyCommand = { Start-PreCopyDeviceConfiguration @args }
PostCopyCommand = { Start-PostCopyDeviceConfiguration @args }
PostExportCommand = { Start-PostExportDeviceConfiguration @args }
GroupId = "DeviceConfiguration"
})
@@ -187,6 +189,7 @@ function Invoke-InitializeModule
# Could work with https://main.iam.ad.ext.azure.com/api/LoginTenantBrandings
#>
Add-ViewItem (New-Object PSObject -Property @{
Title = "Azure Branding"
@@ -196,12 +199,12 @@ function Invoke-InitializeModule
ViewProperties = @("Id")
PreImportCommand = { Start-PreImportAzureBranding @args }
PostListCommand = { Start-PostListAzureBranding @args }
ShowButtons = @("Export","View")
NameProperty = "Id"
Permissons=@("Organization.ReadWrite.All")
Icon = "Branding"
SkipRemoveProperties = @('Id')
})
#>
Add-ViewItem (New-Object PSObject -Property @{
Title = "Enrollment Status Page"
@@ -381,6 +384,7 @@ function Invoke-InitializeModule
ODataMetadata="minimal" # categories property not supported with ODataMetadata full
PostFileImportCommand = { Start-PostFileImportApplications @args }
PreUpdateCommand = { Start-PreUpdateApplication @args }
PreImportCommand = { Start-PreImportCommandApplication @args }
GroupId = "Apps"
})
@@ -393,6 +397,7 @@ function Invoke-InitializeModule
Permissons=@("DeviceManagementServiceConfig.ReadWrite.All")
PreImportAssignmentsCommand = { Start-PreImportAssignmentsAutoPilot @args }
PreDeleteCommand = { Start-PreDeleteAutoPilot @args }
PropertiesToRemoveForUpdate = @('managementServiceAppId')
GroupId = "WinEnrollment"
})
@@ -666,28 +671,28 @@ function Set-EMViewPanel
})
Add-XamlEvent $panel "txtFilter" "Add_LostFocus" ({ #param($obj, $e)
Invoke-FiterBoxChanged $this
Invoke-FilterBoxChanged $this
#$e.Handled = $true
})
Add-XamlEvent $panel "txtFilter" "Add_GotFocus" ({
if($this.Tag -eq "1" -and $this.Text -eq "Filter") { $this.Text = "" }
Invoke-FiterBoxChanged $this
Invoke-FilterBoxChanged $this
})
Add-XamlEvent $panel "txtFilter" "Add_TextChanged" ({
Invoke-FiterBoxChanged $this
Invoke-FilterBoxChanged $this
})
Invoke-FiterBoxChanged ($panel.FindName("txtFilter"))
Invoke-FilterBoxChanged ($panel.FindName("txtFilter"))
$allowDelete = Get-SettingValue "EMAllowDelete"
Set-XamlProperty $panel "btnDelete" "Visibility" (?: ($allowDelete -eq $true) "Visible" "Collapsed")
$global:dgObjects.add_selectionChanged({
Set-XamlProperty $this.Parent "btnView" "IsEnabled" (?: ($global:dgObjects.SelectedItem -eq $null) $false $true)
Set-XamlProperty $this.Parent "btnCopy" "IsEnabled" (?: ($global:dgObjects.SelectedItem -eq $null) $false $true)
Set-XamlProperty $this.Parent "btnDelete" "IsEnabled" (?: ($global:dgObjects.SelectedItem -eq $null -and $global:curObjectType.AllowDelete -ne $false) $false $true)
Set-XamlProperty $this.Parent "btnView" "IsEnabled" (?: ($null -eq $global:dgObjects.SelectedItem) $false $true)
Set-XamlProperty $this.Parent "btnCopy" "IsEnabled" (?: ($null -eq $global:dgObjects.SelectedItem) $false $true)
Set-XamlProperty $this.Parent "btnDelete" "IsEnabled" (?: ($null -eq $global:dgObjects.SelectedItem -and $global:curObjectType.AllowDelete -ne $false) $false $true)
})
# ToDo: Move this to the view object
@@ -696,7 +701,7 @@ function Set-EMViewPanel
{
$dpd.AddValueChanged($global:dgObjects, {
Set-XamlProperty $global:dgObjects.Parent "txtFilter" "Text" ""
$enabled = (?: ($this.ItemsSource -eq $null -or ($this.ItemsSource | measure).Count -eq 0) $false $true)
$enabled = (?: ($null -eq $this.ItemsSource -or ($this.ItemsSource | measure).Count -eq 0) $false $true)
Set-XamlProperty $global:dgObjects.Parent "btnImport" "IsEnabled" $true # Always all Import if ObjectType allows it
Set-XamlProperty $global:dgObjects.Parent "btnExport" "IsEnabled" $enabled
})
@@ -726,7 +731,7 @@ function Set-EMViewPanel
}
}
function Invoke-FiterBoxChanged
function Invoke-FilterBoxChanged
{
param($txtBox)
@@ -751,9 +756,12 @@ function Invoke-FiterBoxChanged
{
$filter = {
param ($item)
foreach($prop in ($item.PSObject.Properties | Where {$_.Name -notin @("IsSelected","Object")}))
return ($null -ne ($item.PSObject.Properties | Where { $_.Name -notin @("IsSelected","Object", "ObjectType") -and $_.Value -match [regex]::Escape($txtBox.Text) }))
foreach($prop in ($item.PSObject.Properties | Where { $_.Name -notin @("IsSelected","Object", "ObjectType")}))
{
if($prop.Value -match $txtBox.Text) { return $true }
if($prop.Value -match [regex]::Escape($txtBox.Text)) { return $true }
}
$false
}
@@ -941,9 +949,82 @@ function Start-PostCopyDeviceConfiguration
windowsPrivacyAccessControls = $objCopyFrom.privacyAccessControls
}
$json = $privacyObj | ConvertTo-Json -Depth 20
$ret = Invoke-GraphRequest -Url "deviceManagement/deviceConfigurations('$($objNew.Id)')/windowsPrivacyAccessControls" -Body $json -Method "POST"
Invoke-GraphRequest -Url "deviceManagement/deviceConfigurations('$($objNew.Id)')/windowsPrivacyAccessControls" -Body $json -Method "POST" | Out-null
}
}
}
}
function Start-PreCopyDeviceConfiguration
{
param($obj, $objectType, $newName)
if(($obj.omaSettings | measure).Count -gt 0)
{
foreach($omaSetting in ($obj.omaSettings | Where isEncrypted -eq $true))
{
if($omaSetting.isEncrypted -eq $false) { continue }
$xmlValue = Invoke-GraphRequest -Url "/deviceManagement/deviceConfigurations/$($obj.Id)/getOmaSettingPlainTextValue(secretReferenceValueId='$($omaSetting.secretReferenceValueId)')"
if($xmlValue.Value)
{
$omaSetting.isEncrypted = $false
$omaSetting.secretReferenceValueId = $null
if($omaSetting.'@odata.type' -eq "#microsoft.graph.omaSettingStringXml" -or
$omaSetting.'value@odata.type' -eq "#Binary")
{
$Bytes = [System.Text.Encoding]::UTF8.GetBytes($xmlValue.Value)
$omaSetting.value = [Convert]::ToBase64String($bytes)
}
else
{
$omaSetting.value = $xmlValue.Value
}
}
}
}
$false
}
function Start-PostExportDeviceConfiguration
{
param($obj, $objectType, $path)
$fileName = "$path\$((Remove-InvalidFileNameChars (Get-GraphObjectName $obj $objectType))).json"
if(($obj.omaSettings | measure).Count -gt 0)
{
$updated = $false
foreach($omaSetting in @(($obj.omaSettings | Where isEncrypted -eq $true)))
{
if($omaSetting.isEncrypted -eq $false) { continue }
# Get decrypted value and mark OMA-URI setting as not encrypted
$xmlValue = Invoke-GraphRequest -Url "/deviceManagement/deviceConfigurations/$($obj.Id)/getOmaSettingPlainTextValue(secretReferenceValueId='$($omaSetting.secretReferenceValueId)')"
if($xmlValue.Value)
{
$omaSetting.isEncrypted = $false
$omaSetting.secretReferenceValueId = $null
if($omaSetting.'@odata.type' -eq "#microsoft.graph.omaSettingStringXml" -or
$omaSetting.'value@odata.type' -eq "#Binary")
{
$Bytes = [System.Text.Encoding]::UTF8.GetBytes($xmlValue.Value)
$omaSetting.value = [Convert]::ToBase64String($bytes)
}
else
{
$omaSetting.value = $xmlValue.Value
}
$updated = $true
}
}
if($updated)
{
$obj | ConvertTo-Json -Depth 20 | Out-File -LiteralPath $fileName -Force
}
}
}
#endregion
@@ -1041,7 +1122,7 @@ function Start-PostImportIntuneBranding
Remove-Property $global:brandingClone $prop
}
$json = ($global:brandingClone | ConvertTo-Json -Depth 20)
$ret = Invoke-GraphRequest -Url "$($objectType.API)/$($obj.Id)" -Body $json -Method "PATCH"
Invoke-GraphRequest -Url "$($objectType.API)/$($obj.Id)" -Body $json -Method "PATCH" | Out-Null
}
function Start-PostGetIntuneBranding
@@ -1285,7 +1366,7 @@ function Start-PostListAppProtection
# App Configurations for Managed Apps are included in App Protections e.g. the /deviceAppManagement/managedAppPolicies API
# For some reason, the $filter option is not supported to filter out these objects
# e.g. not isof(...) to excluded the type, not startsWith(id, 'A_') to exlude based on Id
# These filters generates a request error so fiter them out manually in this function instead
# These filters generates a request error so filter them out manually in this function instead
# The portal is probably doing the same thing since these are included in the return but not in the UI
$objList | Where { $_.Object.'@OData.Type' -ne '#microsoft.graph.targetedManagedAppConfiguration' }
}
@@ -1521,6 +1602,18 @@ function Start-PreUpdateApplication
Remove-Property $obj "appStoreUrl"
}
function Start-PreImportCommandApplication
{
param($obj, $objectType, $file, $assignments)
if($obj.'@OData.Type' -in @('#microsoft.graph.microsoftStoreForBusinessApp','#microsoft.graph.androidStoreApp'))
{
Write-Log "App type '$($obj.'@OData.Type')' not supported for import" 2
@{ "Import" = $false }
}
}
#endregion
#region Group Policy/Administrative Templates functions
@@ -1927,7 +2020,7 @@ function Start-PostFileImportNotifications
{
param($obj, $objectType, $file)
$tmpObj = Get-Content $file | ConvertFrom-Json
$tmpObj = Get-Content -LiteralPath $file | ConvertFrom-Json
foreach($localizedNotificationMessage in $tmpObj.localizedNotificationMessages)
{
@@ -2004,6 +2097,12 @@ function Start-PreImportEnrollmentRestrictions
{
Remove-Property $obj "Id"
}
if($obj.windowsMobileRestriction)
{
# Windows Phone operations are no longer supported
Remove-Property $obj "windowsMobileRestriction"
}
}
function Start-PreDeleteEnrollmentRestrictions

2054
Extensions/IntuneTools.psm1 Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -10,7 +10,7 @@ This module manages Authentication for the application with MSAL. It is also res
#>
function Get-ModuleVersion
{
'3.0.4'
'3.0.5'
}
$global:msalAuthenticator = $null
@@ -20,6 +20,7 @@ function Invoke-InitializeModule
$global:MSALToken = $null
$global:MSALAuthority = $null
$script:AccessableTenants = $null
$global:SkipTokenCacheHelperEx = $null
$global:appSettingSections += (New-Object PSObject -Property @{
Title = "MSAL"
@@ -404,7 +405,15 @@ function Add-MSALPrereq
$RequiredAssemblies.Add($msalPath)
$RequiredAssemblies.Add('System.Security.dll')
Add-Type -Path ($global:AppRootFolder + "\CS\TokenCacheHelperEx.cs") -ReferencedAssemblies $RequiredAssemblies
try
{
Add-Type -Path ($global:AppRootFolder + "\CS\TokenCacheHelperEx.cs") -ReferencedAssemblies $RequiredAssemblies
}
catch
{
$global:SkipTokenCacheHelperEx = $true
Write-LogError "Failed to compile TokenCacheHelperEx. The access token will not be cached. Check write access to the CS folder and ASR policies" $_.Exception
}
}
function Get-MsalAuthenticationToken
@@ -496,7 +505,7 @@ function Get-MSALApp
$msalApp = $appBuilder.Build()
if((Get-SettingValue "CacheMSALToken"))
if($global:SkipTokenCacheHelperEx -ne $true -and (Get-SettingValue "CacheMSALToken"))
{
[TokenCacheHelperEx]::EnableSerialization($msalApp.UserTokenCache, "%LOCALAPPDATA%\CloudAPIPowerShellManagement\msalcahce.bin3")
}
@@ -540,16 +549,16 @@ function Connect-MSALUser
return
}
if (-not ("TokenCacheHelperEx" -as [type]))
if ($global:SkipTokenCacheHelperEx -ne $true -and -not ("TokenCacheHelperEx" -as [type]))
{
Add-MSALPrereq
}
if (-not ("TokenCacheHelperEx" -as [type]))
{
Write-Log "Failed to compile TokenCacheHelperEx class"
return
}
#if (-not ("TokenCacheHelperEx" -as [type]))
#{
# Write-Log "Failed to compile TokenCacheHelperEx class"
# return
#}
$curTicks = $global:MSALToken.ExpiresOn.LocalDateTime.Ticks
@@ -977,7 +986,7 @@ function Get-MSALProfileEllipse
Write-Status ""
})
AddGridObject $otherLogins $lnkButton
Add-GridObject $otherLogins $lnkButton
}
catch {}
}
@@ -1019,7 +1028,7 @@ function Get-MSALProfileEllipse
Write-Status ""
})
AddGridObject $otherLogins $lnkButton
Add-GridObject $otherLogins $lnkButton
$loginPanel.Tag = $this.Content
@@ -1228,7 +1237,7 @@ function Get-MSALProfileEllipse
$grdAccount.Children.Add($lnkButton) | Out-Null
AddGridObject $otherLogins $grdAccount
Add-GridObject $otherLogins $grdAccount
}
catch {}
}
@@ -1271,7 +1280,7 @@ function Get-MSALProfileEllipse
Write-Status ""
})
AddGridObject $otherLogins $lnkButton
Add-GridObject $otherLogins $lnkButton
if(($script:AccessableTenants | measure).Count -gt 1)
{
@@ -1281,7 +1290,7 @@ function Get-MSALProfileEllipse
$lbObj = [Windows.Markup.XamlReader]::Parse("<TextBlock $wpfNS><Bold>Tenants:</Bold></TextBlock>")
$lbObj.Margin = "0,5,0,0"
AddGridObject $otherLogins $lbObj
Add-GridObject $otherLogins $lbObj
foreach($tenant in $script:AccessableTenants)
{
try
@@ -1312,13 +1321,13 @@ function Get-MSALProfileEllipse
}
Write-Status ""
})
AddGridObject $otherLogins $lnkButton
Add-GridObject $otherLogins $lnkButton
}
else
{
$lbObj.Background = $window.TryFindResource("SelectedRowBackgroundColor")
$lbObj.Margin = "0,5,0,0"
AddGridObject $otherLogins $lbObj
Add-GridObject $otherLogins $lbObj
}
}
catch {}

View File

@@ -10,7 +10,7 @@ This module manages Microsoft Grap fuctions like calling APIs, managing graph ob
#>
function Get-ModuleVersion
{
'3.1.4'
'3.1.5'
}
$global:MSGraphGlobalApps = @(
@@ -430,42 +430,48 @@ function Show-GraphObjects
$graphObjects = @(Get-GraphObjects -property $global:curObjectType.ViewProperties -objectType $global:curObjectType)
if(($graphObjects | measure).Count -eq 0) { return }
$dgObjects.AutoGenerateColumns = $false
$dgObjects.Columns.Clear()
$tmpObj = $graphObjects | Select -First 1
$prop = $tmpObj.PSObject.Properties | Where Name -eq "IsSelected"
if($prop)
{
$column = Get-GridCheckboxColumn "IsSelected"
$dgObjects.Columns.Add($column)
if(($graphObjects | measure).Count -gt 0)
{
$tmpObj = $graphObjects | Select -First 1
$column.Header.add_Click({
foreach($item in $global:dgObjects.ItemsSource)
{
$item.IsSelected = $this.IsChecked
}
$global:dgObjects.Items.Refresh()
})
$prop = $tmpObj.PSObject.Properties | Where Name -eq "IsSelected"
if($prop)
{
$column = Get-GridCheckboxColumn "IsSelected"
$dgObjects.Columns.Add($column)
$column.Header.add_Click({
foreach($item in $global:dgObjects.ItemsSource)
{
$item.IsSelected = $this.IsChecked
}
$global:dgObjects.Items.Refresh()
})
}
$tableColumns = @()
# Add other columns
foreach($prop in ($tmpObj.PSObject.Properties | Where {$_.Name -notin @("IsSelected","Object","ObjectType")}))
{
$binding = [System.Windows.Data.Binding]::new($prop.Name)
$column = [System.Windows.Controls.DataGridTextColumn]::new()
$column.Header = $prop.Name
$column.IsReadOnly = $true
$column.Binding = $binding
$tableColumns += $prop.Name
$dgObjects.Columns.Add($column)
}
$ocList = [System.Collections.ObjectModel.ObservableCollection[object]]::new($graphObjects)
$dgObjects.ItemsSource = [System.Windows.Data.CollectionViewSource]::GetDefaultView($ocList)
}
$tableColumns = @()
# Add other columns
foreach($prop in ($tmpObj.PSObject.Properties | Where {$_.Name -notin @("IsSelected","Object","ObjectType")}))
else
{
$binding = [System.Windows.Data.Binding]::new($prop.Name)
$column = [System.Windows.Controls.DataGridTextColumn]::new()
$column.Header = $prop.Name
$column.IsReadOnly = $true
$column.Binding = $binding
$tableColumns += $prop.Name
$dgObjects.Columns.Add($column)
$dgObjects.ItemsSource = $null
}
$ocList = [System.Collections.ObjectModel.ObservableCollection[object]]::new($graphObjects)
$dgObjects.ItemsSource = [System.Windows.Data.CollectionViewSource]::GetDefaultView($ocList)
# Show/Hide buttons based on object type
foreach($ctrl in $spSubMenu.Children)
@@ -1236,7 +1242,7 @@ function Show-GraphBulkDeleteForm
return
}
if(([System.Windows.MessageBox]::Show("Are you sure you want to delete all objects of the selected type(s)?`n`n$selCount type(s) selected", "Delete Objects?", "YesNo", "Warning")) -ne "Yes")
if(([System.Windows.MessageBox]::Show("Are you sure you want to delete all objects of the selected type(s)?`n`n$selCount type(s) selected`n`nEnvironment: $($global:Organization.displayName)", "Delete Objects?", "YesNo", "Warning")) -ne "Yes")
{
return
}
@@ -1331,7 +1337,10 @@ function Import-GraphFile
return
}
Get-GraphMigrationObjectsFromFile
if($global:chkImportAssignments -and $global:chkImportAssignments.IsChecked -eq $true)
{
Get-GraphMigrationObjectsFromFile
}
Get-GraphDependencyObjects $file.ObjectType
@@ -2268,7 +2277,7 @@ function Remove-GraphObjects
return
}
if(([System.Windows.MessageBox]::Show("Are you sure you want to delete $($objectsToDelete.Count) $($global:curObjectType.Title) object(s)?", "Delete Objects?", "YesNo", "Warning")) -ne "Yes")
if(([System.Windows.MessageBox]::Show("Are you sure you want to delete $($objectsToDelete.Count) $($global:curObjectType.Title) object(s)?`n`nEnvironment: $($global:Organization.displayName)", "Delete Objects?", "YesNo", "Warning")) -ne "Yes")
{
return
}
@@ -2344,9 +2353,12 @@ function Copy-GraphObject
{
# Export profile
Write-Status "Export $((Get-GraphObjectName $dgObjects.SelectedItem $global:curObjectType))"
$exportObj = (Get-GraphObject $dgObjects.SelectedItem.Object $global:curObjectType -SkipAssignments).Object
if($global:curObjectType.PreCopyCommand)
{
if((& $global:curObjectType.PreCopyCommand $dgObjects.SelectedItem.Object $global:curObjectType $ret))
if((& $global:curObjectType.PreCopyCommand $exportObj $global:curObjectType $ret))
{
Show-GraphObjects
Write-Status ""
@@ -2354,8 +2366,6 @@ function Copy-GraphObject
}
}
$exportObj = (Get-GraphObject $dgObjects.SelectedItem.Object $global:curObjectType -SkipAssignments).Object
# Convert to Json and back to clone the object
$obj = ConvertTo-Json $exportObj -Depth 10 | ConvertFrom-Json
if($obj)