diff --git a/.github/workflows/Build Module.yml b/.github/workflows/Build Module.yml index f502168..7c9d0f2 100644 --- a/.github/workflows/Build Module.yml +++ b/.github/workflows/Build Module.yml @@ -19,8 +19,13 @@ on: workflow_dispatch: +permissions: + contents: read + jobs: test: + permissions: + contents: write # for stefanzweifel/git-auto-commit-action to push code in repo name: 🧪 Run Tests runs-on: ubuntu-latest strategy: @@ -28,8 +33,13 @@ jobs: steps: + - name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2 + with: + egress-policy: audit + - name: ✅ Checkout Repository - uses: actions/checkout@v4 + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 # Uncomment below to explore what modules/variables/env variables are available in the build image - name: 📦 Modules and Variables Display @@ -45,14 +55,14 @@ jobs: run: Invoke-Build -File .\src\TheCleaners.build.ps1 - name: 🧪 Upload Pester Results - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: pester-results path: .\src\Artifacts\testOutput if-no-files-found: warn - name: 📦 Upload Build - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: zip-archive path: .\src\Archive @@ -60,6 +70,6 @@ jobs: # git-auto-commit-action only runs on Linux-based platforms. - name: 💾 Commit Changes - uses: stefanzweifel/git-auto-commit-action@v5 + uses: stefanzweifel/git-auto-commit-action@b863ae1933cb653a53c021fe36dbb774e1fb9403 # v5.2.0 with: commit_message: 'Commit Build' diff --git a/.github/workflows/Deploy MkDocs.yml b/.github/workflows/Deploy MkDocs.yml index d0acedd..439df7c 100644 --- a/.github/workflows/Deploy MkDocs.yml +++ b/.github/workflows/Deploy MkDocs.yml @@ -14,6 +14,9 @@ on: # Allow manual triggering of the workflow. workflow_dispatch: +permissions: + contents: read + jobs: build: @@ -27,11 +30,16 @@ jobs: cancel-in-progress: true steps: + - name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2 + with: + egress-policy: audit + - name: ✅ Checkout Repository - uses: actions/checkout@v4 + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 - name: 🐍 Setup Python - uses: actions/setup-python@v5 + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 with: python-version: '3.x' # specify the Python version diff --git a/.github/workflows/Publish.yml b/.github/workflows/Publish.yml index 4e59b76..14dc059 100644 --- a/.github/workflows/Publish.yml +++ b/.github/workflows/Publish.yml @@ -1,12 +1,20 @@ name: Publish to PowerShell Gallery on: workflow_dispatch: +permissions: + contents: read + jobs: publish: runs-on: ubuntu-latest steps: + - name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2 + with: + egress-policy: audit + - name: Clone Project Files - uses: actions/checkout@v4 + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 - name: Publish PowerShell Module shell: pwsh run: | diff --git a/src/Archive/TheCleaners_0.0.15_20250311.031804.zip b/src/Archive/TheCleaners_0.0.15_20250311.031804.zip deleted file mode 100644 index 782922e..0000000 Binary files a/src/Archive/TheCleaners_0.0.15_20250311.031804.zip and /dev/null differ diff --git a/src/Artifacts/Invoke-TheCleaners.ps1 b/src/Artifacts/Invoke-TheCleaners.ps1 index feedc72..c1a0af1 100644 --- a/src/Artifacts/Invoke-TheCleaners.ps1 +++ b/src/Artifacts/Invoke-TheCleaners.ps1 @@ -4,17 +4,50 @@ .GUID bec6a004-45da-4062-ab78-b8eae99f29be .AUTHOR Sam Erde .COPYRIGHT (c) 2025 Sam Erde. All rights reserved. -.TAGS Update PowerShell Windows +.TAGS PowerShell Windows Utility .LICENSEURI https://github.com/SamErde/TheCleaners/blob/main/LICENSE .PROJECTURI https://github.com/SamErde/TheCleaners/ #> + function Invoke-TheCleaners { + <# + .SYNOPSIS + Show a welcome message when the module is imported explicitly by the user. + + .DESCRIPTION + This function shows a welcome message to help the user get started when they explicitly import the module. If the + module is automatically imported by invoking one of its exported functions, we assume the user already knows the + command that they want to run and do not show the welcome message. + + .PARAMETER InvokingCommand + A parameter to receive the command line that called this function. This is used to determine if the module was + imported explicitly by the user or automatically by invoking one of its exported functions. This information must + come from outside the function in order to be able to determine what command invoked the script itself. + + .EXAMPLE + Invoke-TheCleaners -InvokingCommand "$( ((Get-PSCallStack)[1]).InvocationInfo.MyCommand )" + + .NOTES + Author: Sam Erde + Company: Sentinel Technologies, Inc + Date: 2025-03-11 + Version: 1.0.0 + #> [CmdletBinding()] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '')] - param() - Write-Host "Thank you for calling The Cleaners! 🧹`nRun " -ForegroundColor Green -NoNewline - Write-Host 'Start-Cleaning' -BackgroundColor Black -ForegroundColor White -NoNewline - Write-Host " to see the services we offer today.`n" -ForegroundColor Green + param ( + # The command that called this function. + [Parameter(Mandatory)] + [string] + $InvokingCommand + ) + + if ($InvokingCommand -match 'ipmo|Import-Module') { + Write-Host "Thank you for calling The Cleaners! 🧹`nRun " -ForegroundColor Green -NoNewline + Write-Host 'Start-Cleaning' -BackgroundColor Black -ForegroundColor White -NoNewline + Write-Host " to see the services we offer today.`n" -ForegroundColor Green + } + } -Invoke-TheCleaners +Invoke-TheCleaners -InvokingCommand "$( ((Get-PSCallStack)[1]).InvocationInfo.MyCommand )" diff --git a/src/Artifacts/TheCleaners.psm1 b/src/Artifacts/TheCleaners.psm1 index e705170..70ef3cd 100644 --- a/src/Artifacts/TheCleaners.psm1 +++ b/src/Artifacts/TheCleaners.psm1 @@ -12,205 +12,53 @@ .GUID bec6a004-45da-4062-ab78-b8eae99f29be .AUTHOR Sam Erde .COPYRIGHT (c) 2025 Sam Erde. All rights reserved. -.TAGS Update PowerShell Windows +.TAGS PowerShell Windows Utility .LICENSEURI https://github.com/SamErde/TheCleaners/blob/main/LICENSE .PROJECTURI https://github.com/SamErde/TheCleaners/ #> -function Invoke-TheCleaners { - [CmdletBinding()] - [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '')] - param() - Write-Host "Thank you for calling The Cleaners! 🧹`nRun " -ForegroundColor Green -NoNewline - Write-Host 'Start-Cleaning' -BackgroundColor Black -ForegroundColor White -NoNewline - Write-Host " to see the services we offer today.`n" -ForegroundColor Green -} - -Invoke-TheCleaners - - -function Convert-SamAccountNameToSID { - <# - .SYNOPSIS - Translates a SamAccountName to a SID. - - .DESCRIPTION - Translates a SamAccountName to a SID. - - .PARAMETER domain - The domain to search for the SamAccountName. - - .PARAMETER SamAccountName - The SamAccountName to translate to a SID. - - .EXAMPLE - Convert-SamAccountNameToSID -Domain "contoso" -SamAccountName "jdoe" - - Translates the SamAccountName "jdoe" to a SID. - - .COMPONENT - TheCleaners - #> - [CmdletBinding()] - param ( - # The Domain - [Parameter(Mandatory)] - [string]$Domain, - - # The SamAccountName - [Parameter(Mandatory)] - [string]$SamAccountName - ) - - $User = New-Object System.Security.Principal.NTAccount($Domain,$SamAccountName) - $SID = $User.Translate([System.Security.Principal.SecurityIdentifier]) - $SID.Value -} # End function Convert-SamAccountNameToSID - -function Convert-SIDtoSamAccountName { +function Invoke-TheCleaners { <# .SYNOPSIS - Translates a SID to a SamAccountName. + Show a welcome message when the module is imported explicitly by the user. .DESCRIPTION - Translates a SID to a SamAccountName. + This function shows a welcome message to help the user get started when they explicitly import the module. If the + module is automatically imported by invoking one of its exported functions, we assume the user already knows the + command that they want to run and do not show the welcome message. - .PARAMETER SID - The SID to translate to a SamAccountName. + .PARAMETER InvokingCommand + A parameter to receive the command line that called this function. This is used to determine if the module was + imported explicitly by the user or automatically by invoking one of its exported functions. This information must + come from outside the function in order to be able to determine what command invoked the script itself. .EXAMPLE - Convert-SIDtoSamAccountName -SID "S-1-5-21-3623811015-3361044348-30300820" - - Translates the SID to a SamAccountName. + Invoke-TheCleaners -InvokingCommand "$( ((Get-PSCallStack)[1]).InvocationInfo.MyCommand )" - .COMPONENT - TheCleaners + .NOTES + Author: Sam Erde + Company: Sentinel Technologies, Inc + Date: 2025-03-11 + Version: 1.0.0 #> [CmdletBinding()] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '')] param ( - # The SID as a string or a SID object. + # The command that called this function. [Parameter(Mandatory)] - $SID - ) - - $SID = New-Object System.Security.Principal.SecurityIdentifier($SID) - $User = $SID.Translate([System.Security.Principal.NTAccount]) - $User.Value -} # End function Convert-SIDtoSamAccountName - - -<# -.SYNOPSIS - Remove files in a path that are older than the specified number of days. - -.DESCRIPTION - Remove files in a path that are older than the specified number of days. This function is used by other functions within the module when removing old files. - -.EXAMPLE - Remove-OldFiles -Path "C:\Windows\Temp" -Days 60 -Recurse - - Removes all files older than 60 does in C:\Windows\Temp with recursion to clean subfolders. -#> -function Remove-OldFiles { - [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')] - [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseSingularNouns')] - param ( - # The path containing files to remove [string] - $Path, - - # How many days worth of logs to retain (how far back to filter) - [int16] - $Days = 60 + $InvokingCommand ) - begin { - - } - - process { - Write-Verbose -Message "Finding and removing files older than $Days." - Get-ChildItem -Path $Path -Recurse | Where-Object { - $_.CreationTime -le ([datetime]::Now.AddDays( -$Days )) - } | Remove-Item + if ($InvokingCommand -match 'ipmo|Import-Module') { + Write-Host "Thank you for calling The Cleaners! 🧹`nRun " -ForegroundColor Green -NoNewline + Write-Host 'Start-Cleaning' -BackgroundColor Black -ForegroundColor White -NoNewline + Write-Host " to see the services we offer today.`n" -ForegroundColor Green } - end { - - } } - -function Show-TCLogo { - <# - .SYNOPSIS - Show an ASCII art logo for The Cleaners. - - .DESCRIPTION - Show a color or plain ASCII art logo for The Cleaners whenever you need it in another function. - - .PARAMETER Plain - Return a plan-text version of the logo instead of multi-colored Write-Host output. - - .EXAMPLE - Show-Logo - - .EXAMPLE - Show-Logo -Plain - - #> - [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost','')] - param ( - [Parameter()] - [switch] - $Plain - ) - - $Version = (Import-PowerShellDataFile -Path $PSScriptRoot\..\TheCleaners.psd1).ModuleVersion - - if ($Plain.IsPresent) { - $Logo = @" - - ╭━━━━┳╮╱╱╱╱╱╭━━━┳╮ - ┃╭╮╭╮┃┃╱╱╱╱╱┃╭━╮┃┃ v$Version - ╰╯┃┃╰┫╰━┳━━╮┃┃╱╰┫┃╭━━┳━━┳━╮ ╭━━┳━┳━━╮ - ╱╱┃┃╱┃╭╮┃┃━┫┃┃╱╭┫┃|┃━┫╭╮┃╭╮╮┃|━┫╭┫━━┫ - ╱╱┃┃╱┃┃┃┃┃━┫┃╰━╯┃╰┫┃━┫╭╮┃||┃┃|━┫|┣━━┃ - ╱╱╰╯╱╰╯╰┻━━╯╰━━━┻━┻━━┻╯╰┻╯╰┻┻━━┻╯╰━━╯ - -"@ - return $Logo - } else { - Write-Host '' - Write-Host ' ╭━━━━┳╮' -ForegroundColor DarkCyan -NoNewline - Write-Host '╱╱╱╱╱' -ForegroundColor Yellow -NoNewline - Write-Host '╭━━━┳╮' -ForegroundColor DarkCyan #NewLine - Write-Host ' ┃╭╮╭╮┃┃' -ForegroundColor DarkCyan -NoNewline - Write-Host '╱╱╱╱╱' -ForegroundColor Yellow -NoNewline - Write-Host '┃╭━╮┃┃' -ForegroundColor DarkCyan -NoNewline #NewLine - Write-Host " v$Version" -ForegroundColor Yellow - Write-Host ' ╰╯┃┃╰┫╰━┳━━╮┃┃' -ForegroundColor DarkCyan -NoNewline - Write-Host '/' -ForegroundColor Yellow -NoNewline - Write-Host '╰┫┃╭━━┳━━┳━╮' -ForegroundColor DarkCyan -NoNewline - Write-Host '*' -ForegroundColor Yellow -NoNewline - Write-Host '╭━━┳━┳━━╮' -ForegroundColor DarkCyan #NewLine - Write-Host ' ╱╱' -ForegroundColor Yellow -NoNewline - Write-Host '┃┃' -ForegroundColor DarkCyan -NoNewline - Write-Host '/' -ForegroundColor Yellow -NoNewline - Write-Host '┃╭╮┃┃━┫┃┃' -ForegroundColor DarkCyan -NoNewline - Write-Host '/' -ForegroundColor Yellow -NoNewline - Write-Host '╭┫┃|┃━┫╭╮┃╭╮╮┃|━┫╭┫━━┫' -ForegroundColor DarkCyan #NewLine - Write-Host ' ╱╱' -ForegroundColor Yellow -NoNewline - Write-Host '┃┃' -ForegroundColor DarkCyan -NoNewline - Write-Host '/' -ForegroundColor Yellow -NoNewline - Write-Host '┃┃┃┃┃━┫┃╰━╯┃╰┫┃━┫╭╮┃||┃┃|━┫|┣━━┃' -ForegroundColor DarkCyan #NewLine - Write-Host ' ╱╱' -ForegroundColor Yellow -NoNewline - Write-Host '┃┃' -ForegroundColor DarkCyan -NoNewline - Write-Host '/' -ForegroundColor Yellow -NoNewline - Write-Host '╰╯╰┻━━╯╰━━━┻━┻━━┻╯╰┻╯╰┻┻━━┻╯╰━━╯' -ForegroundColor DarkCyan #NewLine - Write-Host '' - } -} +Invoke-TheCleaners -InvokingCommand "$( ((Get-PSCallStack)[1]).InvocationInfo.MyCommand )" function Clear-CurrentUserTemp { @@ -528,4 +376,189 @@ function Start-Cleaning { +function Convert-SamAccountNameToSID { + <# + .SYNOPSIS + Translates a SamAccountName to a SID. + + .DESCRIPTION + Translates a SamAccountName to a SID. + + .PARAMETER domain + The domain to search for the SamAccountName. + + .PARAMETER SamAccountName + The SamAccountName to translate to a SID. + + .EXAMPLE + Convert-SamAccountNameToSID -Domain "contoso" -SamAccountName "jdoe" + + Translates the SamAccountName "jdoe" to a SID. + + .COMPONENT + TheCleaners + #> + [CmdletBinding()] + param ( + # The Domain + [Parameter(Mandatory)] + [string]$Domain, + + # The SamAccountName + [Parameter(Mandatory)] + [string]$SamAccountName + ) + + $User = New-Object System.Security.Principal.NTAccount($Domain,$SamAccountName) + $SID = $User.Translate([System.Security.Principal.SecurityIdentifier]) + $SID.Value +} # End function Convert-SamAccountNameToSID + + +function Convert-SIDtoSamAccountName { + <# + .SYNOPSIS + Translates a SID to a SamAccountName. + + .DESCRIPTION + Translates a SID to a SamAccountName. + + .PARAMETER SID + The SID to translate to a SamAccountName. + + .EXAMPLE + Convert-SIDtoSamAccountName -SID "S-1-5-21-3623811015-3361044348-30300820" + + Translates the SID to a SamAccountName. + + .COMPONENT + TheCleaners + #> + [CmdletBinding()] + param ( + # The SID as a string or a SID object. + [Parameter(Mandatory)] + $SID + ) + + $SID = New-Object System.Security.Principal.SecurityIdentifier($SID) + $User = $SID.Translate([System.Security.Principal.NTAccount]) + $User.Value +} # End function Convert-SIDtoSamAccountName + + +<# +.SYNOPSIS + Remove files in a path that are older than the specified number of days. + +.DESCRIPTION + Remove files in a path that are older than the specified number of days. This function is used by other functions within the module when removing old files. + +.EXAMPLE + Remove-OldFiles -Path "C:\Windows\Temp" -Days 60 -Recurse + + Removes all files older than 60 does in C:\Windows\Temp with recursion to clean subfolders. +#> +function Remove-OldFiles { + [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')] + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseSingularNouns')] + param ( + # The path containing files to remove + [string] + $Path, + + # How many days worth of logs to retain (how far back to filter) + [int16] + $Days = 60 + ) + + begin { + + } + + process { + Write-Verbose -Message "Finding and removing files older than $Days." + Get-ChildItem -Path $Path -Recurse | Where-Object { + $_.CreationTime -le ([datetime]::Now.AddDays( -$Days )) + } | Remove-Item + } + + end { + + } +} + + +function Show-TCLogo { + <# + .SYNOPSIS + Show an ASCII art logo for The Cleaners. + + .DESCRIPTION + Show a color or plain ASCII art logo for The Cleaners whenever you need it in another function. + + .PARAMETER Plain + Return a plan-text version of the logo instead of multi-colored Write-Host output. + + .EXAMPLE + Show-Logo + + .EXAMPLE + Show-Logo -Plain + + #> + [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost','')] + param ( + [Parameter()] + [switch] + $Plain + ) + + $Version = (Import-PowerShellDataFile -Path $PSScriptRoot\..\TheCleaners.psd1).ModuleVersion + + if ($Plain.IsPresent) { + $Logo = @" + + ╭━━━━┳╮╱╱╱╱╱╭━━━┳╮ + ┃╭╮╭╮┃┃╱╱╱╱╱┃╭━╮┃┃ v$Version + ╰╯┃┃╰┫╰━┳━━╮┃┃╱╰┫┃╭━━┳━━┳━╮ ╭━━┳━┳━━╮ + ╱╱┃┃╱┃╭╮┃┃━┫┃┃╱╭┫┃|┃━┫╭╮┃╭╮╮┃|━┫╭┫━━┫ + ╱╱┃┃╱┃┃┃┃┃━┫┃╰━╯┃╰┫┃━┫╭╮┃||┃┃|━┫|┣━━┃ + ╱╱╰╯╱╰╯╰┻━━╯╰━━━┻━┻━━┻╯╰┻╯╰┻┻━━┻╯╰━━╯ + +"@ + return $Logo + } else { + Write-Host '' + Write-Host ' ╭━━━━┳╮' -ForegroundColor DarkCyan -NoNewline + Write-Host '╱╱╱╱╱' -ForegroundColor Yellow -NoNewline + Write-Host '╭━━━┳╮' -ForegroundColor DarkCyan #NewLine + Write-Host ' ┃╭╮╭╮┃┃' -ForegroundColor DarkCyan -NoNewline + Write-Host '╱╱╱╱╱' -ForegroundColor Yellow -NoNewline + Write-Host '┃╭━╮┃┃' -ForegroundColor DarkCyan -NoNewline #NewLine + Write-Host " v$Version" -ForegroundColor Yellow + Write-Host ' ╰╯┃┃╰┫╰━┳━━╮┃┃' -ForegroundColor DarkCyan -NoNewline + Write-Host '/' -ForegroundColor Yellow -NoNewline + Write-Host '╰┫┃╭━━┳━━┳━╮' -ForegroundColor DarkCyan -NoNewline + Write-Host '*' -ForegroundColor Yellow -NoNewline + Write-Host '╭━━┳━┳━━╮' -ForegroundColor DarkCyan #NewLine + Write-Host ' ╱╱' -ForegroundColor Yellow -NoNewline + Write-Host '┃┃' -ForegroundColor DarkCyan -NoNewline + Write-Host '/' -ForegroundColor Yellow -NoNewline + Write-Host '┃╭╮┃┃━┫┃┃' -ForegroundColor DarkCyan -NoNewline + Write-Host '/' -ForegroundColor Yellow -NoNewline + Write-Host '╭┫┃|┃━┫╭╮┃╭╮╮┃|━┫╭┫━━┫' -ForegroundColor DarkCyan #NewLine + Write-Host ' ╱╱' -ForegroundColor Yellow -NoNewline + Write-Host '┃┃' -ForegroundColor DarkCyan -NoNewline + Write-Host '/' -ForegroundColor Yellow -NoNewline + Write-Host '┃┃┃┃┃━┫┃╰━╯┃╰┫┃━┫╭╮┃||┃┃|━┫|┣━━┃' -ForegroundColor DarkCyan #NewLine + Write-Host ' ╱╱' -ForegroundColor Yellow -NoNewline + Write-Host '┃┃' -ForegroundColor DarkCyan -NoNewline + Write-Host '/' -ForegroundColor Yellow -NoNewline + Write-Host '╰╯╰┻━━╯╰━━━┻━┻━━┻╯╰┻╯╰┻┻━━┻╯╰━━╯' -ForegroundColor DarkCyan #NewLine + Write-Host '' + } +} + +