functions/Export-AzScriptReport.ps1
function Export-AzScriptReport { <# .SYNOPSIS Exports the results of Read-AzScriptFile to csv or xlsx. .DESCRIPTION Exports the results of Read-AzScriptFile to csv or xlsx. It reformats some of the data and eliminates linebreaks in the "Before" column. In order to generate xlsx files, the additional module "ImportExcel" is required. .PARAMETER Path The path where to write the report to. May be a relative path, must include the filename. The parent folder must already exist. .PARAMETER Delimiter Which delimiter to use when generating a CSV file. Defaults to the current culture, but may be overridden as needed. This affects whether you can open the file in Excel by simple doubleclick or whether you need to first import the data. .PARAMETER InputObject The report objects from Read-AzScriptFile to export. .EXAMPLE PS C:\> Get-ChildItem C:\scripts -Recurse -Filter *.ps1 | Read-AzScriptFile | Export-AzScriptReport -Path .\report.csv Will search all PowerShell code under C:\scripts, search it for AzureAD and MSOnline commands and then export the finidngs to .\report.csv. #> [CmdletBinding()] param ( [Parameter(Position = 0, Mandatory = $true)] [PsfValidateScript('PSFramework.Validate.FSPath.FileOrParent', ErrorString = 'PSFramework.Validate.FSPath.FileOrParent')] [string] $Path, [string] $Delimiter = (Get-PSFConfigValue -FullName 'PSAzureMigrationAdvisor.Export.CsvDelimiter'), [Parameter(ValueFromPipeline = $true)] $InputObject ) begin { $useExcel = $Path -like "*.xlsx" if ($useExcel -and -not (Get-Command Export-Excel -ErrorAction Ignore)) { Stop-PSFFunction -String 'Export-AzScriptReport.NoExcel' -EnableException $true -Cmdlet $PSCmdlet } if ($useExcel) { $steppable = { Export-Excel -Path $Path }.GetSteppablePipeline() } else { $param = @{ Path = $Path } if ($Delimiter) { $param.Delimiter = $Delimiter } else { $param.UseCulture = $true } $steppable = { Export-Csv @param }.GetSteppablePipeline() } try { $steppable.Begin($true) } catch { Stop-PSFFunction -String 'Export-AzScriptReport.Export.Failed' -StringValues $Path -ErrorRecord $_ -EnableException $true -Cmdlet $PSCmdlet } # Ensure mappings for graph commands exist if (0 -eq $script:migrationCommandMapping.Count) { Import-MappingFile } } process { foreach ($datum in $InputObject) { #region Process Messages # Note: This approach breaks down for messages that had multiple lines $msgInfo = @() $msgWarning = @() $msgError = @() $msgTypes = $datum.MessageType -split "`n" $messages = $datum.Message -split "`n" if ($msgTypes) { foreach ($index in 0..$msgTypes.Count) { switch (($msgTypes)[$index]) { 'Info' { $msgInfo += $messages[$index] } 'Information' { $msgInfo += $messages[$index] } 'Warning' { $msgWarning += $messages[$index] } 'Error' { $msgError += $messages[$index] } } } } #endregion Process Messages $mapped = $script:migrationCommandMapping.$($datum.Command) $result = [PSCustomObject][ordered]@{ Path = $datum.Path Command = $datum.Command CommandLine = $datum.CommandLine Before = $datum.Before -replace "``[`r`n]+" -replace '\s+', ' ' # Eliminate backticks and linebreaks After = $datum.After MsgInfo = $msgInfo -join " " MsgWarning = $msgWarning -join " " MsgError = $msgError -join " " FileHash = $datum.Filehash MessageType = $datum.MessageType # Keep in the full dataset, just in case somebody includes multiline messages Messages = $datum.Message ScopesDelegate = $mapped.ScopesDelegate -join ',' ScopesApplication = $mapped.ScopesApplication -join ',' Examples = $mapped.LinkExamples -join ', ' OnlineMapping = 'https://github.com/microsoft/AzureAD-to-MSGraph/blob/main/docs/{0}/{1}.md' -f $mapped.Module, $mapped.Name Organization = $datum.Organization Project = $datum.Project Repository = $datum.Repository Branch = $datum.Branch } $steppable.Process($result) } } end { $steppable.End() } } |