From b9de0638bba5596c0ca5562a89fc97bc77853e7a Mon Sep 17 00:00:00 2001 From: DrIOS <58635327+DrIOSX@users.noreply.github.com> Date: Sun, 9 Jun 2024 10:36:37 -0500 Subject: [PATCH] add: Output type to functions --- source/Private/Assert-ModuleAvailability.ps1 | 1 + source/Private/Connect-M365Suite.ps1 | 1 + source/Private/Disconnect-M365Suite.ps1 | 1 + source/Private/Format-MissingAction.ps1 | 8 ++- source/Private/Format-RequiredModuleList.ps1 | 19 +++++++ source/Private/Get-MostCommonWord.ps1 | 4 +- source/Private/Get-TestDefinitionsObject.ps1 | 4 +- source/Private/Initialize-CISAuditResult.ps1 | 1 + source/Private/Invoke-TestFunction.ps1 | 1 + source/Private/Measure-AuditResult.ps1 | 1 + source/Private/Merge-CISExcelAndCsvData.ps1 | 1 + source/Private/New-MergedObject.ps1 | 2 + source/Private/Update-CISExcelWorksheet.ps1 | 1 + source/Private/Update-WorksheetCell.ps1 | 53 ++++++++++--------- source/Public/Invoke-M365SecurityAudit.ps1 | 17 ++---- source/Public/Sync-CISExcelAndCsvData.ps1 | 1 + .../Format-RequiredModuleList.tests.ps1 | 27 ++++++++++ 17 files changed, 101 insertions(+), 42 deletions(-) create mode 100644 source/Private/Format-RequiredModuleList.ps1 create mode 100644 tests/Unit/Private/Format-RequiredModuleList.tests.ps1 diff --git a/source/Private/Assert-ModuleAvailability.ps1 b/source/Private/Assert-ModuleAvailability.ps1 index 70bb68c..ea4be62 100644 --- a/source/Private/Assert-ModuleAvailability.ps1 +++ b/source/Private/Assert-ModuleAvailability.ps1 @@ -1,4 +1,5 @@ function Assert-ModuleAvailability { + [OutputType([void]) ] param( [string]$ModuleName, [string]$RequiredVersion, diff --git a/source/Private/Connect-M365Suite.ps1 b/source/Private/Connect-M365Suite.ps1 index 3e2404e..1d57549 100644 --- a/source/Private/Connect-M365Suite.ps1 +++ b/source/Private/Connect-M365Suite.ps1 @@ -1,4 +1,5 @@ function Connect-M365Suite { + [OutputType([void])] [CmdletBinding()] param ( [Parameter(Mandatory=$false)] diff --git a/source/Private/Disconnect-M365Suite.ps1 b/source/Private/Disconnect-M365Suite.ps1 index 8d14b89..b338f67 100644 --- a/source/Private/Disconnect-M365Suite.ps1 +++ b/source/Private/Disconnect-M365Suite.ps1 @@ -1,4 +1,5 @@ function Disconnect-M365Suite { + [OutputType([void])] param ( [Parameter(Mandatory)] [string[]]$RequiredConnections diff --git a/source/Private/Format-MissingAction.ps1 b/source/Private/Format-MissingAction.ps1 index 1932fb1..5440486 100644 --- a/source/Private/Format-MissingAction.ps1 +++ b/source/Private/Format-MissingAction.ps1 @@ -1,5 +1,9 @@ function Format-MissingAction { - param ([array]$missingActions) + [CmdletBinding()] + [OutputType([hashtable])] + param ( + [array]$missingActions + ) $actionGroups = @{ "Admin" = @() @@ -22,4 +26,4 @@ function Format-MissingAction { } return $formattedResults -} \ No newline at end of file +} diff --git a/source/Private/Format-RequiredModuleList.ps1 b/source/Private/Format-RequiredModuleList.ps1 new file mode 100644 index 0000000..a3d56f6 --- /dev/null +++ b/source/Private/Format-RequiredModuleList.ps1 @@ -0,0 +1,19 @@ +function Format-RequiredModuleList { + [CmdletBinding()] + [OutputType([string])] + param ( + [Parameter(Mandatory = $true)] + [System.Object[]]$RequiredModules + ) + + $requiredModulesFormatted = "" + foreach ($module in $RequiredModules) { + if ($module.SubModules -and $module.SubModules.Count -gt 0) { + $subModulesFormatted = $module.SubModules -join ', ' + $requiredModulesFormatted += "$($module.ModuleName) (SubModules: $subModulesFormatted), " + } else { + $requiredModulesFormatted += "$($module.ModuleName), " + } + } + return $requiredModulesFormatted.TrimEnd(", ") +} diff --git a/source/Private/Get-MostCommonWord.ps1 b/source/Private/Get-MostCommonWord.ps1 index b626b5e..629a6cb 100644 --- a/source/Private/Get-MostCommonWord.ps1 +++ b/source/Private/Get-MostCommonWord.ps1 @@ -1,4 +1,6 @@ function Get-MostCommonWord { + [CmdletBinding()] + [OutputType([string])] param ( [Parameter(Mandatory = $true)] [string[]]$InputStrings @@ -19,4 +21,4 @@ function Get-MostCommonWord { } else { return $null } -} \ No newline at end of file +} diff --git a/source/Private/Get-TestDefinitionsObject.ps1 b/source/Private/Get-TestDefinitionsObject.ps1 index 6e42d23..da94a14 100644 --- a/source/Private/Get-TestDefinitionsObject.ps1 +++ b/source/Private/Get-TestDefinitionsObject.ps1 @@ -1,4 +1,6 @@ function Get-TestDefinitionsObject { + [CmdletBinding()] + [OutputType([object[]])] param ( [Parameter(Mandatory = $true)] [object[]]$TestDefinitions, @@ -60,4 +62,4 @@ function Get-TestDefinitionsObject { Write-Verbose "Filtered test definitions count: $($TestDefinitions.Count)" return $TestDefinitions -} \ No newline at end of file +} diff --git a/source/Private/Initialize-CISAuditResult.ps1 b/source/Private/Initialize-CISAuditResult.ps1 index 3b2cc94..66adf73 100644 --- a/source/Private/Initialize-CISAuditResult.ps1 +++ b/source/Private/Initialize-CISAuditResult.ps1 @@ -1,5 +1,6 @@ function Initialize-CISAuditResult { [CmdletBinding()] + [OutputType([CISAuditResult])] param ( [Parameter(Mandatory = $true)] [string]$Rec, diff --git a/source/Private/Invoke-TestFunction.ps1 b/source/Private/Invoke-TestFunction.ps1 index 5f6b944..ac5ca2c 100644 --- a/source/Private/Invoke-TestFunction.ps1 +++ b/source/Private/Invoke-TestFunction.ps1 @@ -1,4 +1,5 @@ function Invoke-TestFunction { + [OutputType([CISAuditResult[]])] param ( [Parameter(Mandatory = $true)] [PSObject]$FunctionFile, diff --git a/source/Private/Measure-AuditResult.ps1 b/source/Private/Measure-AuditResult.ps1 index d03265e..041fa25 100644 --- a/source/Private/Measure-AuditResult.ps1 +++ b/source/Private/Measure-AuditResult.ps1 @@ -1,4 +1,5 @@ function Measure-AuditResult { + [OutputType([void])] param ( [Parameter(Mandatory = $true)] [System.Collections.ArrayList]$AllAuditResults, diff --git a/source/Private/Merge-CISExcelAndCsvData.ps1 b/source/Private/Merge-CISExcelAndCsvData.ps1 index 0922c9b..7d2f039 100644 --- a/source/Private/Merge-CISExcelAndCsvData.ps1 +++ b/source/Private/Merge-CISExcelAndCsvData.ps1 @@ -1,5 +1,6 @@ function Merge-CISExcelAndCsvData { [CmdletBinding(DefaultParameterSetName = 'CsvInput')] + [OutputType([PSCustomObject[]])] param ( [Parameter(Mandatory = $true)] [string]$ExcelPath, diff --git a/source/Private/New-MergedObject.ps1 b/source/Private/New-MergedObject.ps1 index 4840d73..50f7497 100644 --- a/source/Private/New-MergedObject.ps1 +++ b/source/Private/New-MergedObject.ps1 @@ -1,4 +1,6 @@ function New-MergedObject { + [CmdletBinding()] + [OutputType([PSCustomObject])] param ( [Parameter(Mandatory = $true)] [psobject]$ExcelItem, diff --git a/source/Private/Update-CISExcelWorksheet.ps1 b/source/Private/Update-CISExcelWorksheet.ps1 index a0d7ae1..9976f76 100644 --- a/source/Private/Update-CISExcelWorksheet.ps1 +++ b/source/Private/Update-CISExcelWorksheet.ps1 @@ -1,4 +1,5 @@ function Update-CISExcelWorksheet { + [OutputType([void])] [CmdletBinding()] param ( [Parameter(Mandatory = $true)] diff --git a/source/Private/Update-WorksheetCell.ps1 b/source/Private/Update-WorksheetCell.ps1 index 622f963..9708c1c 100644 --- a/source/Private/Update-WorksheetCell.ps1 +++ b/source/Private/Update-WorksheetCell.ps1 @@ -1,28 +1,29 @@ - function Update-WorksheetCell { - param ( - $Worksheet, - $Data, - $StartingRowIndex - ) +function Update-WorksheetCell { + [OutputType([void])] + param ( + $Worksheet, + $Data, + $StartingRowIndex + ) - # Check and set headers - $firstItem = $Data[0] - $colIndex = 1 - foreach ($property in $firstItem.PSObject.Properties) { - if ($StartingRowIndex -eq 2 -and $Worksheet.Cells[1, $colIndex].Value -eq $null) { - $Worksheet.Cells[1, $colIndex].Value = $property.Name - } - $colIndex++ - } - - # Iterate over each row in the data and update cells - $rowIndex = $StartingRowIndex - foreach ($item in $Data) { - $colIndex = 1 - foreach ($property in $item.PSObject.Properties) { - $Worksheet.Cells[$rowIndex, $colIndex].Value = $property.Value - $colIndex++ - } - $rowIndex++ - } + # Check and set headers + $firstItem = $Data[0] + $colIndex = 1 + foreach ($property in $firstItem.PSObject.Properties) { + if ($StartingRowIndex -eq 2 -and $Worksheet.Cells[1, $colIndex].Value -eq $null) { + $Worksheet.Cells[1, $colIndex].Value = $property.Name } + $colIndex++ + } + + # Iterate over each row in the data and update cells + $rowIndex = $StartingRowIndex + foreach ($item in $Data) { + $colIndex = 1 + foreach ($property in $item.PSObject.Properties) { + $Worksheet.Cells[$rowIndex, $colIndex].Value = $property.Value + $colIndex++ + } + $rowIndex++ + } +} diff --git a/source/Public/Invoke-M365SecurityAudit.ps1 b/source/Public/Invoke-M365SecurityAudit.ps1 index 231c5d9..5e94add 100644 --- a/source/Public/Invoke-M365SecurityAudit.ps1 +++ b/source/Public/Invoke-M365SecurityAudit.ps1 @@ -183,18 +183,11 @@ function Invoke-M365SecurityAudit { } # Ensure required modules are installed $requiredModules = Get-RequiredModule -AuditFunction - $requiredModulesFormatted = "" - foreach ($module in $requiredModules) { - if ($module.SubModules -and $module.SubModules.Count -gt 0) { - $subModulesFormatted = $module.SubModules -join ', ' - $requiredModulesFormatted += "$($module.ModuleName) (SubModules: $subModulesFormatted), " - } - else { - $requiredModulesFormatted += "$($module.ModuleName), " - } - } - $requiredModulesFormatted = $requiredModulesFormatted.TrimEnd(", ") + # Format the required modules list + $requiredModulesFormatted = Format-RequiredModuleList -RequiredModules $requiredModules + + # Check and install required modules if necessary if (!($NoModuleCheck) -and $PSCmdlet.ShouldProcess("Check for required modules: $requiredModulesFormatted", "Check")) { foreach ($module in $requiredModules) { Assert-ModuleAvailability -ModuleName $module.ModuleName -RequiredVersion $module.RequiredVersion -SubModules $module.SubModules @@ -254,7 +247,7 @@ function Invoke-M365SecurityAudit { } - + Write-Information "A total of $($totalTests) tests were selected to run..." -InformationAction Continue # Import the test functions $testFiles | ForEach-Object { $currentTestIndex++ diff --git a/source/Public/Sync-CISExcelAndCsvData.ps1 b/source/Public/Sync-CISExcelAndCsvData.ps1 index 8842e2f..8e91b95 100644 --- a/source/Public/Sync-CISExcelAndCsvData.ps1 +++ b/source/Public/Sync-CISExcelAndCsvData.ps1 @@ -44,6 +44,7 @@ If the SkipUpdate switch is used, the function returns an array of custom object https://criticalsolutionsnetwork.github.io/M365FoundationsCISReport/#Sync-CISExcelAndCsvData #> function Sync-CISExcelAndCsvData { + [OutputType([void], [PSCustomObject[]])] [CmdletBinding(DefaultParameterSetName = 'CsvInput')] param ( [Parameter(Mandatory = $true)] diff --git a/tests/Unit/Private/Format-RequiredModuleList.tests.ps1 b/tests/Unit/Private/Format-RequiredModuleList.tests.ps1 new file mode 100644 index 0000000..4a2aa69 --- /dev/null +++ b/tests/Unit/Private/Format-RequiredModuleList.tests.ps1 @@ -0,0 +1,27 @@ +$ProjectPath = "$PSScriptRoot\..\..\.." | Convert-Path +$ProjectName = ((Get-ChildItem -Path $ProjectPath\*\*.psd1).Where{ + ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and + $(try { Test-ModuleManifest $_.FullName -ErrorAction Stop } catch { $false } ) + }).BaseName + + +Import-Module $ProjectName + +InModuleScope $ProjectName { + Describe Get-PrivateFunction { + Context 'Default' { + BeforeEach { + $return = Get-PrivateFunction -PrivateData 'string' + } + + It 'Returns a single object' { + ($return | Measure-Object).Count | Should -Be 1 + } + + It 'Returns a string based on the parameter PrivateData' { + $return | Should -Be 'string' + } + } + } +} +