Skip to content

Commit

Permalink
Merge pull request #5501 from salbeck-sit/DSCReport
Browse files Browse the repository at this point in the history
M365DSCReport: Add support for creating a report in CSV-format
  • Loading branch information
ykuijs authored Dec 10, 2024
2 parents 6d04cd6 + 87a40d7 commit d6ed9cb
Show file tree
Hide file tree
Showing 2 changed files with 171 additions and 40 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@
* MISC
* M365DSCDRGUtil
* Add separate check for strings with ordinal comparison and standardized line breaks.
* M365DSCReport
* Add support for creating report in CSV-format


# 1.24.1127.1
Expand Down
209 changes: 169 additions & 40 deletions Modules/Microsoft365DSC/Modules/M365DSCReport.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,105 @@ function New-M365DSCConfigurationToExcel
$excel.Quit()
}

<#
.Description
This function creates a new CSV file from the specified exported configuration
.Functionality
Internal, Hidden
#>
function New-M365DSCConfigurationToCSV
{
[CmdletBinding()]
param
(
[Parameter()]
[Array]
$ParsedContent,

[Parameter(Mandatory = $true)]
[System.String]
$OutputPath,

[Parameter()]
[System.String]
$Delimiter = ','
)

$modelRow = @{'Component Name'=$null; Property=$null; Value = $null}
$row = 0
$csvOutput = @()

foreach ($resource in $parsedContent)
{
$newRow = $modelRow.Clone()
if ($row -gt 0)
{
Write-Verbose -Message "add separator-line in CSV-file between resources"
$newRow.'Component Name' = '======================'
$csvOutput += [pscustomobject]$newRow
$row++
}
$beginRow = $row
foreach ($property in $resource.Keys)
{
$newRow = $modelRow.Clone()
if ($property -ne 'ResourceName' -and $property -ne 'Credential')
{
$newRow.'Component Name' = $resource.ResourceName
$newRow.Property = $property
try
{
if ([System.String]::IsNullOrEmpty($resource.$property))
{
$newRow.Value = "`$Null"
}
else
{
if ($resource.$property.GetType().Name -eq 'Object[]')
{
$value = $resource.$property | Out-String
$newRow.Value = $value
}
else
{
$value = ($resource.$property).ToString().Replace('$', '')
$value = $value.Replace('@', '')
$value = $value.Replace('(', '')
$value = $value.Replace(')', '')
$newRow.Value = $value
}
}
}
catch
{
New-M365DSCLogEntry -Message 'Error during conversion to CSV:' `
-Exception $_ `
-Source $($MyInvocation.MyCommand.Source) `
-TenantId $TenantId `
-Credential $Credential
}

if ($property -in @('Identity', 'Name', 'IsSingleInstance', 'DisplayName'))
{
$OriginPropertyName = $csvOutput[$beginRow].Property
$OriginPropertyValue = $csvOutput[$beginRow].Value
$CurrentPropertyName = $newRow.Property
$CurrentPropertyValue = $newRow.Value

$csvOutput[$beginRow].Property = $CurrentPropertyName
$csvOutput[$beginRow].Value = $CurrentPropertyValue
$newRow.Property = $OriginPropertyName
$newRow.Value = $OriginPropertyValue
}
$csvOutput += [pscustomobject]$newRow
$row++
}
}
}
$csvOutput | Export-Csv -Path $OutputPath -Encoding UTF8 -Delimiter $Delimiter -NoTypeInformation
}

<#
.Description
This function creates a report from the specified exported configuration,
Expand Down Expand Up @@ -586,7 +685,7 @@ function New-M365DSCReportFromConfiguration
param
(
[Parameter(Mandatory = $true)]
[ValidateSet('Excel', 'HTML', 'JSON', 'Markdown')]
[ValidateSet('Excel', 'HTML', 'JSON', 'Markdown', 'CSV')]
[System.String]
$Type,

Expand All @@ -598,51 +697,81 @@ function New-M365DSCReportFromConfiguration
[System.String]
$OutputPath
)
DynamicParam # parameter 'Delimiter' is only available when Type = 'CSV'
{
$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new()
if ($Type -eq 'CSV')
{
$delimiterAttr = [System.Management.Automation.ParameterAttribute]::New()
$delimiterAttr.Mandatory = $false
$attributeCollection = [System.Collections.ObjectModel.Collection[System.Attribute]]::New()
$attributeCollection.Add($delimiterAttr)
$delimiterParam = [System.Management.Automation.RuntimeDefinedParameter]::New("Delimiter", [System.String], $attributeCollection)
$delimiterParam.Value = ';' # default value, comma makes a mess when importing a CSV-file in Excel
$paramDictionary.Add("Delimiter", $delimiterParam)
}
return $paramDictionary
}

# Validate that the latest version of the module is installed.
Test-M365DSCModuleValidity

#Ensure the proper dependencies are installed in the current environment.
Confirm-M365DSCDependencies

#region Telemetry
$data = [System.Collections.Generic.Dictionary[[String], [String]]]::new()
$data.Add('Event', 'Report')
$data.Add('Type', $Type)
Add-M365DSCTelemetryEvent -Data $data -Type 'NewReport'
#endregion

[Array] $parsedContent = Initialize-M365DSCReporting -ConfigurationPath $ConfigurationPath

if ($null -ne $parsedContent)
begin
{
switch ($Type)
if ($PSBoundParameters.ContainsKey('Delimiter'))
{
'Excel'
{
New-M365DSCConfigurationToExcel -ParsedContent $parsedContent -OutputPath $OutputPath
}
'HTML'
{
$template = Get-Item $ConfigurationPath
$templateName = $Template.Name.Split('.')[0]
New-M365DSCConfigurationToHTML -ParsedContent $parsedContent -OutputPath $OutputPath -TemplateName $templateName
}
'JSON'
{
New-M365DSCConfigurationToJSON -ParsedContent $parsedContent -OutputPath $OutputPath
}
'Markdown'
{
$template = Get-Item $ConfigurationPath
$templateName = $Template.Name.Split('.')[0]
New-M365DSCConfigurationToMarkdown -ParsedContent $parsedContent -OutputPath $OutputPath -TemplateName $templateName
}
$Delimiter = $PSBoundParameters.Delimiter
}
}
else
process # required with DynamicParam
{
Write-Warning -Message "Parsed content was null. No report was generated."

# Validate that the latest version of the module is installed.
Test-M365DSCModuleValidity

#Ensure the proper dependencies are installed in the current environment.
Confirm-M365DSCDependencies

#region Telemetry
$data = [System.Collections.Generic.Dictionary[[String], [String]]]::new()
$data.Add('Event', 'Report')
$data.Add('Type', $Type)
Add-M365DSCTelemetryEvent -Data $data -Type 'NewReport'
#endregion

[Array] $parsedContent = Initialize-M365DSCReporting -ConfigurationPath $ConfigurationPath

if ($null -ne $parsedContent)
{
switch ($Type)
{
'Excel'
{
New-M365DSCConfigurationToExcel -ParsedContent $parsedContent -OutputPath $OutputPath
}
'HTML'
{
$template = Get-Item $ConfigurationPath
$templateName = $Template.Name.Split('.')[0]
New-M365DSCConfigurationToHTML -ParsedContent $parsedContent -OutputPath $OutputPath -TemplateName $templateName
}
'JSON'
{
New-M365DSCConfigurationToJSON -ParsedContent $parsedContent -OutputPath $OutputPath
}
'Markdown'
{
$template = Get-Item $ConfigurationPath
$templateName = $Template.Name.Split('.')[0]
New-M365DSCConfigurationToMarkdown -ParsedContent $parsedContent -OutputPath $OutputPath -TemplateName $templateName
}
'CSV'
{
New-M365DSCConfigurationToCSV -ParsedContent $parsedContent -OutputPath $OutputPath -Delimiter $Delimiter
}
}
}
else
{
Write-Warning -Message "Parsed content was null. No report was generated."
}
}
}

Expand Down

0 comments on commit d6ed9cb

Please sign in to comment.