IMPORTANT UPDATE 11/05/2022 – This is updated for v5.6!!!
Overview
I did not want my RetroPie to be cluttered with ROMs I did not want. I only wanted the original games, I did not want duplicates or revisions, and I only wanted games in English so I could read the on screen text. For example, the NES has about 716 officially licensed games and the No-Intro 2018 ROM set has about 2,748 games in it. I wanted to reduce that number closer to the officially licensed games count to save space and reduce the amount of ROMs I would have to scroll through each time. I decided to create the below powershell scripts based on the No-Intro 2018 ROM set to accomplish my goal, which I’ll explain each step in detail.
http://sigkillit.com/wp-content/uploads/2022/11/Clean-NoIntro2018_v56.zip
You can also download the older archived scripts, but I HIGHLY RECOMMEND sticking with latest scripts!
The No-Intro 2018 ROM set includes the following game systems that are compatible with RetroPie/Emulationstation:
- Atari: 2600
- Atari: 5200
- Atari: 7800
- Atari: Jaguar
- Atari: Lynx
- Atari: ST
- Bandai: WonderSwan
- Bandai: WonderSwan Color
- Coleco: ColecoVision
- GCE: Vectrex
- Microsoft: MSX
- NEC: PC Engine / TurboGrafx 16
- Nintendo: Family Computer Disk System
- Nintendo: Game Boy
- Nintendo: Game Boy Advance
- Nintendo: Game Boy Color
- Nintendo: Nintendo 64
- Nintendo: Nintendo Entertainment System
- Nintendo: Super Nintendo Entertainment System
- Nintendo: Virtual Boy
- SNK: Neo Geo Pocket
- SNK: Neo Geo Pocket Color
- Sega: 32X
- Sega: Game Gear
- Sega: Master System / Mark III
- Sega: Mega Drive / Genesis
- Sega: SG-1000
The No-Intro ROMs follow a pretty standardized naming scheme such as:
- Battletoads (Europe).zip
- Battletoads (Japan).zip
- Battletoads (USA).zip
- Captain Skyhawk (Europe).zip
- Captain Skyhawk (USA) (Rev A).zip
- Captain Skyhawk (USA).zip
As you can see, the base name of the ROM is followed by detailed descriptions such as the region released, revision, language, etc which is contained in parentheses. The script is based on using this naming scheme to get unique ROM base names by grabbing everything to the left of the first parentheses. [ Note: As of v5.5 you can use the $romSplitchar variable in each systems Filter to customize what character to split on, and by default I set it to a left Parenthesis ‘(‘ ]. It then further analyzes the results based on filters for each game system, which decide the ROM to keep. The default filters are set to prefer the USA version and the earliest revision (On older gaming systems, later revisions usually just made changes like the sprite used for a character or the color and not necessarily “bug” fixes like more modern game systems). Using the examples above, the script would keep “Battletoads (USA).zip) and “Captain Skyhawk (USA).zip”. See below for further details on using the scripts.
1_Clean-NoIntroRoms.ps1
See supplemental scripts:
Global Variable Definitions:
- $global:scriptName
- Name of the Script, defaults to full name of the script
- $global:scriptVersion
- $global:romNoIntroDirectory
- Source No-Intro 2018 Game System ROM Directory, each game system should have a folder in here that matches in $global:romNoIntroHashTable. Default is “C:\Games\No-Intro 2018\”
- $global:romCleanDirectory
- Destination directory to copy No-Intro 2018 ROMs to, each game system will have a folder in here that matches in $global:romNoIntroHashTable (Default is the RetroPie game system directory names). This way it never modifies the ROMs in the source directory. Default is “C:\Games\RetroPie\roms\”
- $global:romCleanDirectoryPurge
- Remove each game system directory in $global:romCleanDirectory so it does not exist before copying the ROMs. Default is $true
- $global:romOverWrite
- Overwrite existing ROMs in each game system directory in $global:romCleanDirectory if the game system directory exists. When $false, it will not copy any ROMs into the game system directory if it exists. When $true, it will copy and overwrite ROMs into the game system directory if it exists, but will not remove any additional ROMs or files that exist. Default is $false
- $global:romFilterDirectory
- Directory that stores the “filters” for each game system. The filters are .ps1 files named using the RetroPie directory name defined in $global:romNoIntroHashTable. I have customized the filters for each system and included them by default. You can modify them to your liking or if they do not exist, the script will generate a generic filter for each system. Default is a “filters” folder in the same directory as the script
- $global:romRetropieDirectory
- Location of the ROM directory on the RetroPie, which is used if you want the script to auto copy the ROMs to your RetroPie. Default is “\\retropie\roms\”
- $global:romRetropieDirectoryPurge
- Purge each game system’s ROM directory before copying ROMs to the RetroPie. Default is $true
- $global:romRetropieUpload
- Auto copy the ROMs from $global:romCleanDirectory to $global:romRetropieDirectory. Default is $true
- $global:logFile
- Log file output of the entire run and additional log files are placed in the same directory. Default is a “logs” directory in the same directory as the script with a log name that matches the script’s base name. Ex: .\logs\1_Clean-NoIntroRom.log
- $global:logOverwrite
- Overwrite the log files. Default is $true
- $global:logVerbose
- Show the full details of how it decides which ROMs to keep. This should only be used for debugging purposes and will increase the run time of the script. Default is $false
- $global:romNoIntroHashTable
- Hashtable setting each game systems directory name on RetroPie and in the No-Intro 2018 complete ROM set. Default directory names are used for each
Filter File Variable Definitions:
I have customized and included these since v5.0 and they are located in .\filters\<gamesystem>.ps1. If you want customize which ROMs are kept for each system, this is what you want to change.
- $romSplitchar
- Customize the character used to split a ROM name to determine unique ROM names by using everything to the left of this character. By default this is set to a left Parenthesis ‘(‘. For example, when comparing “Darkwing Duck (USA).zip” and “Darkwing Duck (Europe).zip”, the unique ROM name would be “Darkwing Duck “. The script would then use $romsSortOrder to determine which of the two files to keep, which would be the USA version if you use my default filters.
- $romUnzip
- Unzip ROMs for emulators that don’t support .zip. $false will NOT unzip them and $true will unzip them
- $romsDoNotDelete
- Any exact ROM name (including extension) in this list will NOT be deleted. ROMs listed here will not be deleted even in they match a value in $romsExceptions or they are NOT the Primary ROM via $romSortOrder
- Ex: “Castlevania (USA) (Rev A).zip”
- $romsExceptions
- Any ROMs containing these strings or exact ROM name will be removed unless the exact ROM name is in $romsDoNotDelete
- $romsSortOrder
- Preferred sorting order to pick 1 Primary ROM to keep when evaluating duplicates. Uses regular expressions to define the preferred sorting order based on language, and if there are no matches it will determine the primary ROM by alphabetical sort. ROMs in $romsExceptions will not be deleted even if it is not determined to be the Primary ROM
#1_Clean-NoIntroRoms.ps1
#v5.6
# -Added Description to Filters
# -Added 4_UpdateVersion.ps1 Script
#v5.5
# -Added $romSplitchar variable to Filters to customize how unique ROM names are determined
# -Everything to the left of this character is determined to be the unique ROM name.
# -If left blank, all ROMs will be skipped. Recommended to keep default '(' for No-Intro ROMs
# -Fixed logs in 1_Clean-NoIntroRoms_Exceptions.log so they stay in order
#v5.4
# -Fixed bug in Get-NoIntroRomsExceptions When ROM Name Does Not Contain '('
# -Fixed bug setting non-duplicate primary ROM due to name missing $romSplitchar resulting in 0 matches
# -Updated Filters by adding ROM extensions as last resort when matching, otherwise primary ROM is never set
# -Added $global:scriptVersion to Set Filter Version in Get-NoIntroDefaultFilters Function
#v5.3
# -Re-Added Function Get-NoIntroDefaultFilters which was accidently removed from version 5.2
# -Renamed "config" to "filter" Main Function Section 1 Log
# -Added Changelog in Comments
#v5.2
# -Added variables for Write-Out Colors and Updated to Write-Out v1.3
# -Updated Filters for scraping
#v5.1
# -Fixed minor bugs and updating filters for scraping
#v5.0
# -Rewrote the code to be modular by importing filters for each game system instead of using separate scripts
# -Added variables to define where to store game system filters and logs
# -Replaced $MyInvocation.MyCommand.Name with $PSCommandPath which requires Powershell 3 or greater
# -Replaced Log-Write with Write-Out function which requires Powershell 4 or greater
# -Added Atari Jaguar because it can run on PI4 with proper customization
# -Fixed bug with romsDoNotDelete
# -Fixed bug where exceptions were not removed from uniqueRom causing it to still evaluate them for duplicates
$global:scriptName = $PSCommandPath
$global:scriptVersion = "v5.6"
$global:romNoIntroDirectory = "C:\Games\Complete ROM Sets\No-Intro 2018\"
$global:romCleanDirectory = "C:\Games\RetroPie\roms\"
$global:romCleanDirectoryPurge = $true
$global:romOverWrite = $false
$global:romFilterDirectory = (Split-Path -Path $PSCommandPath -Parent) + "\filters\"
$global:romRetropieDirectory = "\\retropie\roms\"
$global:romRetropieDirectoryPurge = $true
$global:romRetropieUpload = $true
$global:logFile = (Split-Path -Path $PSCommandPath -Parent) + "\logs\" + (Split-Path -Path $PSCommandPath.Replace(".ps1",".log") -Leaf)
$global:logOverwrite = $true
$global:logVerbose = $false
$global:romNoIntroHashTable = [ordered]@{
#RetroPieDirName = No-IntroDirName
"atari2600" = "Atari - 2600"
"atari5200" = "Atari - 5200"
"atari7800" = "Atari - 7800 [Headered]"
"atarijaguar" = "Atari - Jaguar"
"atarilynx" = "Atari - Lynx [Headered]"
"atarist" = "Atari - ST"
"coleco" = "Coleco - ColecoVision"
"fds" = "Nintendo - Family Computer Disk System [headered]"
"gamegear" = "Sega - Game Gear"
"gb" = "Nintendo - Game Boy"
"gba" = "Nintendo - Game Boy Advance"
"gbc" = "Nintendo - Game Boy Color"
"mastersystem" = "Sega - Master System - Mark III"
"megadrive" = "Sega - Mega Drive - Genesis"
"msx" = "Microsoft - MSX"
"n64" = "Nintendo - Nintendo 64"
"nes" = "Nintendo - Nintendo Entertainment System [headered]"
"ngp" = "SNK - Neo Geo Pocket"
"ngpc" = "SNK - Neo Geo Pocket Color"
"pcengine" = "NEC - PC Engine - TurboGrafx 16"
"sega32x" = "Sega - 32X"
"sg-1000" = "Sega - SG-1000"
"snes" = "Nintendo - Super Nintendo Entertainment System"
"vectrex" = "GCE - Vectrex"
"virtualboy" = "Nintendo - Virtual Boy"
"wonderswan" = "Bandai - WonderSwan"
"wonderswancolor" = "Bandai - WonderSwan Color"
}
#Output Color Variables
$global:colorMain = "Green"
$global:colorSub1 = "DarkGreen"
$global:colorSub2 = "Green"
$global:colorSub3 = "DarkRed"
$global:colorOk = "Green"
$global:colorWarn = "Yellow"
$global:colorError = "Red"
Function Main()
{
#Powershell 4 or greater is required
If (!($PSVersionTable.PSVersion.Major -ge 4) -OR ($PSVersionTable.PSVersion -eq $null))
{
Write-Host -ForegroundColor $global:colorError "Powershell v4 or greater is required, quitting script!"
Exit
}
#Create Log File
If ($global:logOverwrite -eq $true)
{
Write-Out -ForegroundColor $global:colorMain -Text "****************************************************************" -LogFile $global:logFile -Overwrite
}
Else
{
Write-Out -ForegroundColor $global:colorMain -Text "****************************************************************" -LogFile $global:logFile
}
Write-Out -ForegroundColor $global:colorMain -Text "SECTION 1: INITIALIZE" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorMain -Text "****************************************************************" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorMain -Text "* Script Name : $($global:scriptName)" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorMain -Text "* Version: : $($global:scriptVersion)" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorMain -Text "* ROM No-Intro Dir : $($global:romNoIntroDirectory)" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorMain -Text "* ROM Clean Dir : $($global:romCleanDirectory)" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorMain -Text "* ROM Clean Dir Purge : $($global:romCleanDirectoryPurge)" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorMain -Text "* ROM Overwrite : $($global:romOverWrite)" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorMain -Text "* ROM Filter Dir : $($global:romFilterDirectory)" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorMain -Text "* ROM Retropie Dir : $($global:romRetropieDirectory)" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorMain -Text "* ROM Retropie Dir Purge : $($global:romRetropieDirectoryPurge)" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorMain -Text "* ROM Upload to Retropie : $($global:romRetropieUpload)" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorMain -Text "* Log File : $($global:logFile)" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorMain -Text "* Log Overwrite : $($global:logOverwrite)" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorMain -Text "* Log Verbose : $($global:logVerbose)" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorMain -Text "* Description : Cleanup 2018 No-Intro ROMs" -LogFile $global:logFile
$tStart = (Get-Date)
Write-Out -ForegroundColor $global:colorMain -Text "* Start Time : $($tStart)" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorMain -Text "****************************************************************" -LogFile $global:logFile
$tLog = $global:logFile.Replace(".log","_Exceptions.log")
$tFilterDir = $global:romFilterDirectory
Write-Out -PreLine 1 -ForegroundColor $global:colorMain -Text "****************************************************************" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorMain -Text "SECTION 2: BUILD LIST OF UNIQUE EXCEPTIONS FILTERS FOR NO-INTRO ROMS" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorMain -Text "****************************************************************" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorMain -Text "* Log File : $($tLog)" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorMain -Text "* Log Overwrite : $($global:logOverwrite)" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorMain -Text "* Description : Use No-Intro Naming Scheme to Build a List of Unique Exception Filters Used to Remove" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorMain -Text "* Unwanted ROMs For Each System Ex: (Beta), (Proto),(Japan)" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorMain -Text "****************************************************************" -LogFile $global:logFile
$ArgumentHash = @{
Source = $global:romNoIntroDirectory
FilterDir = $tFilterDir
HashTable = $global:romNoIntroHashTable
Log = $tLog
LogOverwrite = $global:logOverwrite
}
Get-NoIntroRomsExceptions @ArgumentHash
Write-Out -PreLine 1 -ForegroundColor $global:colorMain -Text "****************************************************************" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorMain -Text "SECTION 3: CLEANUP NO-INTRO ROMS" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorMain -Text "****************************************************************" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorMain -Text "* Log File : Per Game System" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorMain -Text "* Log Overwrite : $($global:logOverwrite)" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorMain -Text "* Description : Use filters to copy No-Intro 2018 ROMs from Source to clean directory" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorMain -Text "****************************************************************" -LogFile $global:logFile
ForEach ($key in $global:romNoIntroHashTable.keys)
{
$tLog = "$((Split-Path -Path $global:logFile -Parent))\$($key).log"
$tFilters = "$($global:romFilterDirectory)$($key).ps1"
$tSource = "$($global:romNoIntroDirectory)$($global:romNoIntroHashTable[$key])"
$tDestination = "$($global:romCleanDirectory)$($key)"
Write-Out -PreLine 1 -ForegroundColor $global:colorMain -Text "****************************************************************" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorMain -Text "PROCESS: $key" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorMain -Text "****************************************************************" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorSub1 -Text "ROM Description : $($global:romNoIntroHashTable[$key])" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorSub1 -Text "ROM Filters : $($tFilters)" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorSub1 -Text "ROM Source Dir : $($tSource)" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorSub1 -Text "ROM Clean Dir : $($tDestination)" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorSub1 -Text "ROM Clean Dir Purge : $($global:romCleanDirectoryPurge)" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorSub1 -Text "ROM Overwrite : $($global:romOverWrite)" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorSub1 -Text "Log File : $($tLog)" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorSub1 -Text "Log Overwrite : $($global:logOverwrite)" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorSub1 -Text "Log Verbose : $($global:logVerbose)" -LogFile $global:logFile
If ($global:romCleanDirectoryPurge)
{
If(Test-Path -LiteralPath "$($tDestination)")
{
Write-Out -ForegroundColor $global:colorSub1 -Text "ROM Clean Dir Exists, Purge Before Processing" -LogFile $global:logFile
Write-Out -ForegroundColor DarkRed -Text "Purge: $($tDestination)" -LogFile $global:logFile
Remove-Item "$($tDestination)" -Recurse -Force -Confirm:$false
}
Else
{
Write-Out -ForegroundColor $global:colorWarn -Text "ROM Clean Dir Does Not Exist, Skip Purge Before Processing" -LogFile $global:logFile
}
}
$ArgumentHash = @{
System = $key
Description = $global:romNoIntroHashTable[$key]
Source = $tSource
Destination = $tDestination
Overwrite = $global:romOverWrite
Filters = $tFilters
Log = $tLog
LogOverwrite = $global:logOverwrite
LogVerbose = $global:logVerbose
}
Clean-NoIntroRoms @ArgumentHash
Write-Out -ForegroundColor $global:colorSub1 -Text "Processing $($key) Complete" -LogFile $global:logFile
}
Write-Out -PreLine 1 -ForegroundColor $global:colorMain -Text "****************************************************************" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorMain -Text "SECTION 4: END RESULTS" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorMain -Text "****************************************************************" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorMain -Text "* ROM Retropie Dir : $($global:romRetropieDirectory)" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorMain -Text "* ROM Retropie Dir Purge : $($global:romRetropieDirectoryPurge)" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorMain -Text "* ROM Upload to Retropie : $($global:romRetropieUpload)" -LogFile $global:logFile
If ($global:romRetropieUpload)
{
#Loop Each ROM Directory and Copy to RetroPie
ForEach ($key in $global:romNoIntroHashTable.keys)
{
$tSource = "$($global:romCleanDirectory)$($key)"
$tDestination = "$($global:romRetropieDirectory)$($key)"
Write-Out -PreLine 1 -ForegroundColor $global:colorMain -Text "* $($key)" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorMain -Text "* =======================================================" -LogFile $global:logFile
If (Test-Path -LiteralPath "$($tSource)")
{
Write-Out -ForegroundColor $global:colorMain -Text "* Source Exist: $($tSource)" -LogFile $global:logFile
If (Test-Path -LiteralPath "$($tDestination)")
{
Write-Out -ForegroundColor $global:colorMain -Text "* Dest Exist: $($tDestination)" -LogFile $global:logFile
If ($global:romRetropieDirectoryPurge)
{
Write-Out -ForegroundColor $global:colorError -Text "* Purge: $($tDestination)" -LogFile $global:logFile
Get-ChildItem "$($tDestination)" -Recurse | Remove-Item -Force -Confirm:$false
}
Write-Out -ForegroundColor $global:colorMain -Text "* Copy ROMs from '$($tSource)' to '$($tDestination)'" -LogFile $global:logFile
Copy-Item -Path "$($tSource)\*" -Destination "$($tDestination)" -Recurse -Force
}
Else
{
Write-Out -ForegroundColor $global:colorWarn -Text "* Dest NOT Exist: $($tDestination)" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorMain -Text "* Create Folder: $($tDestination)" -LogFile $global:logFile
If (New-Item -ItemType Directory -Path $tDestination -Force)
{
Write-Out -ForegroundColor $global:colorMain -Text "* Copy ROMs from '$($tSource)' to '$($tDestination)'" -LogFile $global:logFile
Copy-Item -Path "$($tSource)\*" -Destination "$($tDestination)" -Recurse -Force
}
Else
{
Write-Out -ForegroundColor $global:colorError -Text "* ERROR Creating Destination No ROMs Copied!" -LogFile $global:logFile
}
}
}
Else
{
Write-Out -ForegroundColor $global:colorError -Text "* Source NOT Exist: $($tSource)" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorError -Text "* ERROR CANNOT COPY!!!" -LogFile $global:logFile
}
}
}
$tEnd = (Get-Date)
Write-Out -ForegroundColor $global:colorMain -Text "* End Time : $($tEnd)" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorMain -Text "* Elapsed Time : $([math]::Round(($tEnd-$tStart).totalseconds, 2)) seconds" -LogFile $global:logFile
Write-Out -ForegroundColor $global:colorMain -Text "****************************************************************" -LogFile $global:logFile
}
Function Get-NoIntroRomsExceptions()
{
Param
(
[Parameter(Mandatory=$true)]
[Alias("Source")]
[string]$RomDir,
[Parameter(Mandatory=$true)]
[string]$FilterDir = "",
[Parameter(Mandatory=$true)]
[Alias("HashTable")]
[System.Collections.Specialized.OrderedDictionary]$RomHashTable,
[Parameter(Mandatory=$true)]
[Alias("Log")]
[string]$LogFile,
[Parameter(Mandatory=$false)]
[string]$LogOverwrite = $false
)
If ($LogOverwrite -eq $true)
{
Write-Out -ForegroundColor $global:colorMain -Text " " -LogFile $LogFile -Overwrite
}
Else
{
Write-Out -ForegroundColor $global:colorMain -Text " " -LogFile $LogFile
}
$colUniqueRomsAll = @()
ForEach ($key in $RomHashTable.keys)
{
#Process Current ROM Directory
Write-Out -PreLine 1 -ForegroundColor $global:colorMain -Text "PROCESS: $($RomDir)$($RomHashTable[$key])" -LogFile $LogFile
Write-Out -ForegroundColor $global:colorMain -Text "=======================================================" -LogFile $LogFile
#Confirm No-Intro ROM Directory Exists
If(!(Test-Path -LiteralPath "$($RomDir)$($RomHashTable[$key])"))
{
#Directory Does Not Exist
Write-Out -ForegroundColor $global:colorError -Text "ERROR: ROM Directory Does Not Exist!!!" -LogFile $LogFile
}
Else
{
#Directory Exists
Write-Out -ForegroundColor $global:colorSub1 -Text "Directory Exists: Continue Processing" -LogFile $LogFile
#Check If Filter Exists Then Set $romSplitChar
If (Test-Path -LiteralPath "$($FilterDir)$($key).ps1")
{
Write-Out -ForegroundColor $global:colorSub1 -Text "Filter Exists: Import Unique Split Char Variable" -LogFile $LogFile
. "$($FilterDir)$($key).ps1"
If ([string]::IsNullOrEmpty($romSplitchar))
{
Write-Out -ForegroundColor $global:colorSub1,$global:colorWarn -Text "Unique Split Char: ","Null Or Empty Do Not Process" -LogFile $LogFile
}
Else
{
Write-Out -ForegroundColor $global:colorSub1 -Text "Unique Split Char: '$($romSplitchar)'" -LogFile $LogFile
$colRoms = @()
$colUniqueRoms = @()
$colRoms = Get-ChildItem -LiteralPath "$($RomDir)$($RomHashTable[$key])"
$colRoms | ForEach-Object `
{
If ($_.BaseName.Contains($romSplitchar))
{
$colUniqueRoms += $romSplitchar + $_.BaseName.split($romSplitchar,2)[1]
}
}
$colUniqueRoms = $colUniqueRoms | Sort-Object -Unique
$colUniqueRomsAll += $colUniqueRoms
Write-Out -ForegroundColor $global:colorMain -Text "Found $($colUniqueRoms.Count) Potential Exceptions to Filter:" -LogFile $LogFile
ForEach ($name in $colUniqueRoms)
{
Write-Out -ForegroundColor $global:colorSub1 -Text "$($name)" -LogFile $LogFile
}
}
}
Else
{
Write-Out -ForegroundColor $global:colorWarn -Text "Filter Not Exist: Do Not Process" -LogFile $LogFile
}
}
}
Write-Out -PreLine 1 -ForegroundColor $global:colorMain -Text "PROCESS: Combined Unique Exceptions" -LogFile $LogFile
Write-Out -ForegroundColor $global:colorMain -Text "=======================================================" -LogFile $LogFile
$colUniqueRomsAll = $colUniqueRomsAll | Sort-Object -Unique
Write-Out -ForegroundColor $global:colorMain -Text "Found $($colUniqueRomsAll.Count) Combined Potential Exceptions to Filter:" -LogFile $LogFile
ForEach ($name in $colUniqueRomsAll)
{
Write-Out -ForegroundColor $global:colorSub1 -Text "$($name)" -LogFile $LogFile
}
}
Function Clean-NoIntroRoms()
{
Param
(
[Parameter(Mandatory=$true)]
[Alias("System")]
[string]$GameSystem,
[Parameter(Mandatory=$true)]
[Alias("Description")]
[string]$GameDescription,
[Parameter(Mandatory=$true)]
[Alias("Source")]
[string]$RomSource,
[Parameter(Mandatory=$true)]
[Alias("Destination")]
[string]$RomDestination,
[Parameter(Mandatory=$true)]
[Alias("Overwrite")]
[bool]$RomOverwrite,
[Parameter(Mandatory=$true)]
[Alias("Filters")]
[string]$RomFilters,
[Parameter(Mandatory=$true)]
[Alias("Log")]
[string]$LogFile,
[Parameter(Mandatory=$false)]
[bool]$LogOverwrite = $true,
[Parameter(Mandatory=$false)]
[bool]$LogVerbose = $false
)
$countTotal = 0
$countUnique = 0
$countExceptionsDeleted = 0
$countDuplicatesDeleted = 0
$countNonDuplicatesDeleted = 0
#Create Log File
If ($LogOverwrite -eq $true)
{
Write-Out -ForegroundColor $global:colorMain -Text "$($GameSystem.ToUpper()) (STEP 1/6): Processing Information" -LogFile $LogFile -Overwrite
}
Else
{
Write-Out -ForegroundColor $global:colorMain -Text "$($GameSystem.ToUpper()) (STEP 1/6): Processing Information" -LogFile $LogFile
}
Write-Out -ForegroundColor $global:colorMain -Text "================================================================" -LogFile $LogFile
Write-Out -ForegroundColor $global:colorSub1 -Text "Game System : $($GameDescription)" -LogFile $LogFile
$timeStart = (Get-Date)
Write-Out -ForegroundColor $global:colorSub1 -Text "Start Time : $($timeStart)" -LogFile $LogFile
Write-Out -ForegroundColor $global:colorSub1 -Text "ROM Source Dir : $($RomSource)" -LogFile $LogFile
Write-Out -ForegroundColor $global:colorSub1 -Text "ROM Clean Dir : $($RomDestination)" -LogFile $LogFile
Write-Out -ForegroundColor $global:colorSub1 -Text "ROMs Overwrite : $($RomOverwrite)" -LogFile $LogFile
Write-Out -ForegroundColor $global:colorSub1 -Text "ROM Filters : $($RomFilters)" -LogFile $LogFile
Write-Out -ForegroundColor $global:colorSub1 -Text "Log File : $($LogFile)" -LogFile $LogFile
Write-Out -ForegroundColor $global:colorSub1 -Text "Log Overwrite : $($LogOverwrite)" -LogFile $LogFile
Write-Out -ForegroundColor $global:colorSub1 -Text "Log Verbose : $($LogVerbose)" -LogFile $LogFile
If(!(Test-Path -LiteralPath $RomSource))
{
Write-Out -ForegroundColor $global:colorError -Text "ERROR: ROM Source Directory Does Not Exist - Stop Processing!" -LogFile $LogFile
Return
}
If(!(Test-Path -LiteralPath $RomFilters))
{
#Set Defaults For: $romUnzip, $romsDoNotDelete, $romsExceptions, $romsSortOrder
Write-Out -ForegroundColor $global:colorWarn -Text "WARNING: ROM Filters File Does Not Exist, Set Default Values - Continue Processing!" -LogFile $LogFile
Write-Out -ForegroundColor $global:colorWarn -Text "$($RomFilters): Write `$romSplitchar Default" -LogFile $LogFile
Write-Out -ForegroundColor $global:colorWarn -Text "$($RomFilters): Write `$romUnzip Default" -LogFile $LogFile
Write-Out -ForegroundColor $global:colorWarn -Text "$($RomFilters): Write `$romsDoNotDelete Default" -LogFile $LogFile
Write-Out -ForegroundColor $global:colorWarn -Text "$($RomFilters): Write `$romsExceptions Default" -LogFile $LogFile
Write-Out -ForegroundColor $global:colorWarn -Text "$($RomFilters): Write `$romsSortOrder Default" -LogFile $LogFile
$DefaultFilters = Get-NoIntroDefaultFilters (Split-Path -Path $RomFilters -Leaf)
Write-Out -ForegroundColor $global:colorWarn -Text "Write to File: $($RomFilters)" -LogFile $LogFile
$nf = New-Item -Path $RomFilters -type file -force -Value $DefaultFilters
}
#Set Custom Variables to Cleanup ROMs for Each System by Dot Sourcing($romUnzip, $romsDoNotDelete, $romsExceptions, $romsSortOrder)
Write-Out -ForegroundColor $global:colorSub1 -Text "Import Variables from $($RomFilters)" -LogFile $LogFile
. "$($RomFilters)"
Write-Out -ForegroundColor $global:colorMain -Text "ROM Exceptions to Keep" -LogFile $LogFile
Write-Out -ForegroundColor $global:colorMain -Text "-------------------------------------------------------" -LogFile $LogFile
If (($romsDoNotDelete.Count -le 0) -OR $romsDoNotDelete -eq $null)
{
Write-Out -ForegroundColor $global:colorWarn -Text "None" -LogFile $LogFile
}
Else
{
ForEach ($rom in $romsDoNotDelete)
{
Write-Out -ForegroundColor $global:colorSub1 -Text "$($rom)" -LogFile $LogFile
}
}
Write-Out -ForegroundColor $global:colorMain -Text "Delete ROMs Containing" -LogFile $LogFile
Write-Out -ForegroundColor $global:colorMain -Text "-------------------------------------------------------" -LogFile $LogFile
If (($romsExceptions.Count -le 0) -OR $romsExceptions -eq $null)
{
Write-Out -ForegroundColor $global:colorWarn -Text "None" -LogFile $LogFile
}
Else
{
ForEach ($rom in $romsExceptions)
{
Write-Out -ForegroundColor $global:colorSub1 -Text "$($rom)" -LogFile $LogFile
}
}
Write-Out -ForegroundColor $global:colorMain -Text "ROM Sort Order" -LogFile $LogFile
Write-Out -ForegroundColor $global:colorMain -Text "-------------------------------------------------------" -LogFile $LogFile
ForEach ($rom in $romsSortOrder)
{
Write-Out -ForegroundColor $global:colorSub1 -Text "$($rom)" -LogFile $LogFile
}
#Get List of ROMs and Unique ROMs in the original No-Intro 2018 ROM set
Write-Out -ForegroundColor $global:colorMain -Text "$($GameSystem.ToUpper()) (STEP 2/6): Get All No-Intro ROMs and Unique ROMs to Process" -LogFile $LogFile
Write-Out -ForegroundColor $global:colorMain -Text "================================================================" -LogFile $LogFile
[System.Collections.ArrayList]$colRoms = @()
(Get-ChildItem -LiteralPath $RomSource).ForEach({$obj = [PSCustomObject]@{ FullName = $_.FullName; Name = $_.Name};$colRoms.add($obj)|out-null})
If ([string]::IsNullOrEmpty($romSplitchar))
{
#No Split Character to Determine Unique ROM Name
Write-Out -ForegroundColor $global:colorWarn -Text "No Split Character to Determine Unique ROM Name" -LogFile $LogFile
#Remove All ROMs
$colRoms.Clear()
}
Else
{
$colUniqueRoms = @()
$colUniqueRoms = $colRoms | ForEach-Object { $_.Name.split($romSplitchar)[0] } | Sort-Object -Unique
#Count Total Original Source ROMs and Original Source Unique ROMs
$countTotal = $colRoms.count
$countUnique = $colUniqueRoms.count
Write-Out -ForegroundColor $global:colorSub1 -Text "Total ROMs: $($countTotal)" -LogFile $LogFile
Write-Out -ForegroundColor $global:colorSub1 -Text "Total Unique ROMs: $($countUnique)" -LogFile $LogFile
#Remove Exceptions - Further Speeds Things Up By Not Having to Process As Much
Write-Out -ForegroundColor $global:colorMain -Text "$($GameSystem.ToUpper()) (STEP 3/6): Remove Exceptions" -LogFile $LogFile
Write-Out -ForegroundColor $global:colorMain -Text "================================================================" -LogFile $LogFile
If (($romsExceptions.Count -le 0) -OR $romsExceptions -eq $null)
{
Write-Out -ForegroundColor $global:colorWarn -Text "None" -LogFile $LogFile
}
Else
{
#Remove Exception from colRoms Array
For ($i=0; $i -lt $colRoms.Count; $i++)
{
ForEach ($romException in $romsExceptions)
{
#Check If Current ROM Matches Exception
If ($colRoms[$i].Name -match [regex]::escape($romException))
{
#Exception Found (Flag Delete)
#Special Case Do Not Delete ROMs Check
$romDND = $false
If ($romsDoNotDelete.Count -gt 0)
{
ForEach ($doNotDelete in $romsDoNotDelete)
{
If ($doNotDelete -eq $colRoms[$i].Name)
{
#Found Special Case (Flag NOT Delete)
$romDND = $true
break
}
}
}
#Check to Delete or Not
If ($romDND -eq $true)
{
Write-Out -ForegroundColor $global:colorSub1 -Text "DO NOT DELETE EXCEPTON (Special Case): $($colRoms[$i].Name)" -LogFile $LogFile
}
Else
{
#Delete ROM
Write-Out -ForegroundColor DarkRed -Text "DELETE EXCEPTION '$($romException)': $($colRoms[$i].Name)" -LogFile $LogFile
$colRoms.RemoveAt($i)
$i--
$countExceptionsDeleted++
}
break
}
}
}
}
#Update Unique ROMs to Remove Exceptions
$colUniqueRoms = $colRoms | ForEach-Object { $_.Name.split($romSplitchar)[0] } | Sort-Object -Unique
#Identify Primary ROM to Keep and Remove Duplicates
Write-Out -ForegroundColor $global:colorMain -Text "$($GameSystem.ToUpper()) (STEP 4/6): Identify Primary ROM and Remove Duplicates" -LogFile $LogFile
Write-Out -ForegroundColor $global:colorMain -Text "================================================================" -LogFile $LogFile
ForEach ($uniqueRom in $colUniqueRoms)
{
#Determine Duplicates For Each Unique ROM Name
$colDuplicateRoms = @()
#$colDuplicateRoms = $colRoms.Name -match ("^"+[regex]::escape($uniqueRom)+"\(")
$colDuplicateRoms = $colRoms.Name -match ("^"+[regex]::escape($uniqueRom)+[regex]::escape($romSplitchar))
Write-Out -ForegroundColor $global:colorMain -Text "PROCESS: '$($uniqueRom)'" -LogFile $LogFile
If ($colDuplicateRoms.count -gt 1)
{
#Determine Primary ROM In Each Duplicate ROM Set By Matching Sorting Preference
:regloop ForEach ($sortRegex in $romsSortOrder )
{
#Process ROMS That Match A Sorting Order
$primaryRom = ""
$colRomsToSort = @()
[array]$colRomsToSort = $colDuplicateRoms -match $sortRegex
$colRomsToSort = $colRomsToSort | Sort-Object
If ($colRomsToSort.count -ge 1)
{
#Find Primary ROM To Keep
If ($LogVerbose -eq $true)
{
Write-Out -ForegroundColor $global:colorSub1 -Text "TEST REGEX ($($colRomsToSort.count) Matches): $($sortRegex)" -LogFile $LogFile
}
For($i = $colRomsToSort.GetLowerBound(0); $i -le $colRomsToSort.GetUpperBound(0); $i++)
{
$matchRomException = $false
If ($LogVerbose -eq $true)
{
Write-Out -ForegroundColor $global:colorSub1 -Text "Primary ROM Found (Match $($i + 1) of $($colRomsToSort.GetUpperBound(0) + 1)): $($colRomsToSort[$i])" -LogFile $LogFile
}
#Check Primary ROM For Exceptions
ForEach ($romException in $romsExceptions)
{
If ($colRomsToSort[$i] -match [regex]::escape($romException))
{
$matchRomException = $true
If ($LogVerbose -eq $true)
{
Write-Out -ForegroundColor $global:colorSub1 -Text "Primary ROM Exception Found (Match $($i+1) of $($colRomsToSort.count): $($romException)" -LogFile $LogFile
}
break
}
}
#Set Primary ROM
If ($matchRomException -eq $false)
{
$primaryRom = $colRomsToSort[$i]
break regloop
}
}
}
Else
{
If ($LogVerbose -eq $true)
{
Write-Out -ForegroundColor $global:colorSub1 -Text "SKIP REGEX (No Matches): $($sortRegex)" -LogFile $LogFile
}
}
}
#Display Primary ROM Result
If ($primaryRom -eq "")
{
If ($LogVerbose -eq $true)
{
Write-Out -ForegroundColor $global:colorSub1 -Text "Primary ROM Set: No Primary Found!" -LogFile $LogFile
}
}
Else
{
If ($LogVerbose -eq $true)
{
Write-Out -ForegroundColor $global:colorSub1 -Text "Primary ROM Set: $($primaryRom)" -LogFile $LogFile
}
}
#Remove All Duplicate ROMS Except Primary ROM
ForEach ($duplicateRom in $colDuplicateRoms)
{
#Primary ROM Found
If ($duplicateRom -eq $primaryRom)
{
#Keep Primary ROM
Write-Out -ForegroundColor $global:colorSub1 -Text "KEEP(Primary): $($duplicateRom)" -LogFile $LogFile
}
Else
{
#Special Case Do Not Delete ROMs Check
$romDND = $false
If ($romsDoNotDelete.Count -gt 0)
{
ForEach ($doNotDelete in $romsDoNotDelete)
{
If ($doNotDelete -eq $duplicateRom)
{
$romDND = $true
break
}
}
}
If ($romDND -eq $true)
{
Write-Out -ForegroundColor $global:colorSub1 -Text "DO NOT DELETE (Special Case): $($duplicateRom)" -LogFile $LogFile
}
Else
{
If ($primaryRom -eq "")
{
#No Primary Found Delete Duplicate
Write-Out -ForegroundColor DarkRed -Text "DELETE(No Primary Found): $($duplicateRom)" -LogFile $LogFile
}
Else
{
#Not The Primary ROM Delete Duplicate Or Exception
Write-Out -ForegroundColor DarkRed -Text "DELETE(Duplicate/Exception): $($duplicateRom)" -LogFile $LogFile
}
#Delete ROM
For ($i=0; $i -lt $colRoms.Count; $i++)
{
If ($colRoms[$i].Name -eq $duplicateRom)
{
$colRoms.RemoveAt($i)
$i--
}
}
$countDuplicatesDeleted++
}
}
}
}
Else
{
#NOTE - $colDuplicateRoms acts as a variable (type=object) because there's a single item in the array!
#If No Matches Found Manualy Set $colDuplicateRoms (Means ROM did not have $romSplitchar and returned file name + extension)
If ($colDuplicateRoms.count -eq 0)
{
$colDuplicateRoms = $uniqueRom
}
#Non-Duplicate ROM Primary By Default
If ($LogVerbose -eq $true)
{
Write-Out -ForegroundColor $global:colorSub1 -Text "SKIP REGEX (No Duplicates):" -LogFile $LogFile
Write-Out -ForegroundColor $global:colorSub1 -Text "Primary ROM Set (Non-Duplicate): $($colDuplicateRoms)" -LogFile $LogFile
}
#Check Primary ROM For Exceptions
$matchRomException = $false
ForEach ($romException in $romsExceptions)
{
#Check If Current ROM Matches Exception
If ($colDuplicateRoms -match [regex]::escape($romException))
{
#Exception Found (Flag Delete)
$matchRomException = $true
#Special Case Do Not Delete ROMs Check
$romDND = $false
If ($romsDoNotDelete.Count -gt 0)
{
ForEach ($doNotDelete in $romsDoNotDelete)
{
If ($doNotDelete -eq $colDuplicateRoms)
{
#Found Special Case (Flag NOT Delete)
$romDND = $true
break
}
}
}
break
}
}
#Check to Delete or Not
If ($matchRomException -eq $false)
{
Write-Out -ForegroundColor $global:colorSub1 -Text "KEEP(Primary Non-Duplicate): $($colDuplicateRoms)" -LogFile $LogFile
}
Else
{
#Delete
If ($romDND -eq $true)
{
#Special Case Keep
Write-Out -ForegroundColor $global:colorSub1 -Text "DO NOT DELETE (Special Case Non-Duplicate): $($colDuplicateRoms)" -LogFile $LogFile
}
Else
{
#Delete ROM
Write-Out -ForegroundColor DarkRed -Text "DELETE (Exception Non-Duplicate) '$($romException)': $($colDuplicateRoms)" -LogFile $LogFile
For ($i=0; $i -lt $colRoms.Count; $i++)
{
If ($colRoms[$i].Name -eq $duplicateRom)
{
$colRoms.RemoveAt($i)
$i--
}
}
}
}
}
}
}
#Copy NoIntro ROMs
Write-Out -ForegroundColor $global:colorMain -Text "$($GameSystem.ToUpper()) (STEP 5/6): Copy No-Intro ROMs" -LogFile $LogFile
Write-Out -ForegroundColor $global:colorMain -Text "================================================================" -LogFile $LogFile
#Confirm Source ROM Directory Exists
If (Test-Path -LiteralPath $RomSource)
{
Write-Out -ForegroundColor $global:colorSub1 -Text "Source Exist: '$($RomSource)'" -LogFile $LogFile
#Confirm Destination Directory Exists
If (Test-Path -LiteralPath $RomDestination)
{
#Destination Directory Exists - Overwrite?
If ($RomOverwrite -eq $true)
{
Write-Out -ForegroundColor $global:colorWarn -Text "Destination EXIST (Overwrite): '$($RomDestination)'" -LogFile $LogFile
Write-Out -ForegroundColor $global:colorSub1 -Text "Copy $($colRoms.count) ROMs from '$($RomSource)*' to '$($RomDestination)'" -LogFile $LogFile
ForEach ($rom in $colRoms)
{
Copy-Item -LiteralPath $rom.FullName -Destination $RomDestination -Recurse -Force
}
}
Else
{
Write-Out -ForegroundColor $global:colorWarn -Text "Destination EXIST (Do Not Overwrite): '$($RomDestination)'" -LogFile $LogFile
Write-Out -ForegroundColor $global:colorWarn -Text "No Files Copied!'" -LogFile $LogFile
}
}
Else
{
Write-Out -ForegroundColor $global:colorSub1 -Text "Destination Not Exist: '$($RomDestination)'" -LogFile $LogFile
Write-Out -ForegroundColor $global:colorSub1 -Text "Create Folder: '$($RomDestination)'" -LogFile $LogFile
If (New-Item -ItemType Directory -Path $RomDestination -Force)
{
Write-Out -ForegroundColor $global:colorSub1 -Text "Copy $($colRoms.count) ROMs from '$($RomSource)' to '$($RomDestination)'" -LogFile $LogFile
ForEach ($rom in $colRoms)
{
Copy-Item -LiteralPath $rom.FullName -Destination $RomDestination -Recurse -Force
}
}
Else
{
Write-Out -ForegroundColor $global:colorError -Text "ERROR Creating Destination No ROMs Copied!" -LogFile $LogFile
}
}
}
Else
{
Write-Out -ForegroundColor $global:colorError -Text "Source NOT Exist: '$($RomSource)'" -LogFile $LogFile
Write-Out -ForegroundColor $global:colorError -Text "ERROR CANNOT COPY!!!" -LogFile $LogFile
}
#Optionally Unzip ROMs Incase .zip Not Supported By Emulator
If ($romUnzip -eq $true)
{
Write-Out -ForegroundColor $global:colorSub1 -Text "Unzip ROMs In: '$($RomDestination)'" -LogFile $LogFile
$colRoms = Get-ChildItem -LiteralPath $RomDestination -Filter "*.zip"
ForEach ($rom in $colRoms)
{
Expand-Archive $rom.FullName -DestinationPath $RomDestination -Force
Remove-Item -LiteralPath $rom.FullName -Force
}
}
#Results
Write-Out -ForegroundColor $global:colorMain -Text "$($GameSystem.ToUpper()) (STEP 6/6): Processing Results" -LogFile $LogFile
Write-Out -ForegroundColor $global:colorMain -Text "================================================================" -LogFile $LogFile
Write-Out -ForegroundColor $global:colorSub1 -Text "ROMs TOTAL : $($countTotal)" -LogFile $LogFile
Write-Out -ForegroundColor $global:colorSub1 -Text "ROMs UNIQUE : $($countUnique)" -LogFile $LogFile
Write-Out -ForegroundColor $global:colorSub1 -Text "ROMs Exceptions Deleted : $($countExceptionsDeleted)" -LogFile $LogFile
Write-Out -ForegroundColor $global:colorSub1 -Text "ROMs Dups Deleted : $($countDuplicatesDeleted)" -LogFile $LogFile
Write-Out -ForegroundColor $global:colorSub1 -Text "ROMs Non-Dup Deleted : $($countNonDuplicatesDeleted)" -LogFile $LogFile
Write-Out -ForegroundColor $global:colorSub1 -Text "ROMs Total Deleted : $($countExceptionsDeleted + $countDuplicatesDeleted + $countNonDuplicatesDeleted)" -LogFile $LogFile
Write-Out -ForegroundColor $global:colorSub1 -Text "ROMs Total After Clean : $($countTotal - ($countExceptionsDeleted + $countDuplicatesDeleted + $countNonDuplicatesDeleted))" -LogFile $LogFile
Write-Out -ForegroundColor $global:colorSub1 -Text "Start Time : $($timeStart)" -LogFile $LogFile
$timeEnd = (Get-Date)
Write-Out -ForegroundColor $global:colorSub1 -Text "End Time : $($timeEnd)" -LogFile $LogFile
Write-Out -ForegroundColor $global:colorSub1 -Text "Elapsed Time : $([math]::Round(($timeEnd-$timeStart).totalseconds, 2)) seconds" -LogFile $LogFile
}
Function Get-NoIntroDefaultFilters
{
Param (
[Parameter(Mandatory=$false)]
[string]
$Name = "",
[Parameter(Mandatory=$false)]
[string]
$Splitchar = "(",
[Parameter(Mandatory=$false)]
[string]
$Unzip = '$false'
)
Begin
{
#Nothing to Do Here
}
Process
{
$DefaultFilters = @"
#$Name $global:scriptVersion
#No-Intro 2018 ROM Set
#Default Case Sensitive Character to Determine Unique ROM Name (Blank = Skip)
`$romSplitchar = "$Splitchar"
#Unzip ROMs That Do Not Support .ZIP Files On RetroPie
`$romUnzip = $Unzip
`n
"@
$DefaultFilters += @'
#Any Exact ROM Name (Including Extension) In This List Will Not Be Deleted
#-ROMs listed here will NOT be deleted even if they match a value in romsExceptions
#-ROMs listed here will NOT be deleted if it's NOT the Primary ROM via romsSortOrder
#-Ex: "Castlevania (USA) (Rev A).zip"
$romsDoNotDelete = @(
)
#Any ROMs Containing These Strings Or Exact ROM Name Will Be Removed Unless the Exact ROM Name Is In romsDoNotDelete
$romsExceptions = @(
"[BIOS]"
,"[b]"
,"(Alpha)"
,"(Beta)"
,"(Beta 1)"
,"(Beta 2)"
,"(Beta 3)"
,"(Proto)"
,"(Proto 1)"
,"(Proto 2)"
,"(Promo)"
,"(Sample)"
,"(Debug Version)"
,"(Enhancement Chip)"
,"(GameCube Edition)"
,"(Promo, Virtual Console)"
,"(Virtual Console)"
,"(Wii Virtual Console)"
,"(Wii U Virtual Console)"
,"(Asia)"
,"(Australia)"
,"(Brazil)"
,"(Canada)"
,"(China)"
,"(France)"
,"(Germany)"
,"(Hong Kong)"
,"(Italy)"
,"(Japan)"
,"(Korea)"
,"(Netherlands)"
,"(Russia)"
,"(Spain)"
,"(Sweden)"
,"(Taiwan)"
)
#Preferred Sorting Order to Pick 1 Primary ROM to Keep When Evaluating Duplicates
#-Order Selects Specific Names followed by more generalized names based around language
#-ROMs in romsExceptions will not be deleted even if it is not determined as the primary
#-Ex: "Joust (USA).zip" would be primary over "Joust (Japan).zip"
$romsSortOrder = @(
#---------------------------------------
#---USA PREFERRED ORDER---
#---------------------------------------
#(USA).zip
"\(USA\)\.zip"
#(USA) (Unl).zip
,"\(USA\)\s*\(Unl\)\.zip"
#(USA) (En,*).zip
,"\(USA\)\s*\(En(,|\+|Ca|Da|De|En|Es|Fi|Fr|It|Ja|Nl|No|Pl|Pt|Sv|Zh)*?\)\.zip"
#(USA) (En,*) (Unl).zip
,"\(USA\)\s*\(En(,|\+|Ca|Da|De|En|Es|Fi|Fr|It|Ja|Nl|No|Pl|Pt|Sv|Zh)*?\)\s*\(Unl\)\.zip"
#(USA) <Anything Except (Alt ) or (Rev ) or (Demo)>.zip
,"^(?=.*?\(USA\))((?!\(Alt\s*[A-Z0-9]{0,2}\)|\(Rev\s*[A-Z0-9\.]{0,4}\)|\(Demo\)).)*$"
#(USA, Europe).zip
,"\(USA,\s*Europe\)\.zip"
#(USA, Europe) (Unl).zip
,"\(USA,\s*Europe\)\s*\(Unl\)\.zip"
#(USA, Europe) (En,*).zip
,"\(USA,\s*Europe\)\s*\(En(,|\+|Ca|Da|De|En|Es|Fi|Fr|It|Ja|Nl|No|Pl|Pt|Sv|Zh)*?\)\.zip"
#(USA, Europe) (En,*) (Unl).zip
,"\(USA,\s*Europe\)\s*\(En(,|\+|Ca|Da|De|En|Es|Fi|Fr|It|Ja|Nl|No|Pl|Pt|Sv|Zh)*?\)\s*\(Unl\)\.zip"
#(USA, Europe) <Anything Except (Alt ) or (Rev ) or (Demo)>.zip
,"^(?=.*?\(USA,\s*Europe\))((?!\(Alt\s*[A-Z0-9]{0,2}\)|\(Rev\s*[A-Z0-9\.]{0,4}\)|\(Demo\)).)*$"
#(Japan, USA).zip
,"\(Japan,\s*USA\)\.zip"
#(Japan, USA) (Unl).zip
,"\(Japan,\s*USA\)\s*\(Unl\)\.zip"
#(Japan, USA) (En,*).zip
,"\(Japan,\s*USA\)\s*\(En(,|\+|Ca|Da|De|En|Es|Fi|Fr|It|Ja|Nl|No|Pl|Pt|Sv|Zh)*?\)\.zip"
#(Japan, USA) (En,*) (Unl).zip
,"\(Japan,\s*USA\)\s*\(En(,|\+|Ca|Da|De|En|Es|Fi|Fr|It|Ja|Nl|No|Pl|Pt|Sv|Zh)*?\)\s*\(Unl\)\.zip"
#(Japan, USA) <Anything Except (Alt ) or (Rev ) or (Demo)>.zip
,"^(?=.*?\(Japan,\s*USA\))((?!\(Alt\s*[A-Z0-9]{0,2}\)|\(Rev\s*[A-Z0-9\.]{0,4}\)|\(Demo\)).)*$"
#(USA, Asia).zip
,"\(USA,\s*Asia\)\.zip"
#(USA, Asia) (Unl).zip
,"\(USA,\s*Asia\)\s*\(Unl\)\.zip"
#(USA, Asia) (En,*).zip
,"\(USA,\s*Asia\)\s*\(En(,|\+|Ca|Da|De|En|Es|Fi|Fr|It|Ja|Nl|No|Pl|Pt|Sv|Zh)*?\)\.zip"
#(USA, Asia) (En,*) (Unl).zip
,"\(USA,\s*Asia\)\s*\(En(,|\+|Ca|Da|De|En|Es|Fi|Fr|It|Ja|Nl|No|Pl|Pt|Sv|Zh)*?\)\s*\(Unl\)\.zip"
#(USA, Asia) <Anything Except (Alt ) or (Rev ) or (Demo)>.zip
,"^(?=.*?\(USA,\s*Asia\))((?!\(Alt\s*[A-Z0-9]{0,2}\)|\(Rev\s*[A-Z0-9\.]{0,4}\)|\(Demo\)).)*$"
#(USA, Australia).zip
,"\(USA,\s*Australia\)\.zip"
#(USA, Australia) (Unl).zip
,"\(USA,\s*Australia\)\s*\(Unl\)\.zip"
#(USA, Australia) (En,*).zip
,"\(USA,\s*Australia\)\s*\(En(,|\+|Ca|Da|De|En|Es|Fi|Fr|It|Ja|Nl|No|Pl|Pt|Sv|Zh)*?\)\.zip"
#(USA, Australia) (En,*) (Unl).zip
,"\(USA,\s*Australia\)\s*\(En(,|\+|Ca|Da|De|En|Es|Fi|Fr|It|Ja|Nl|No|Pl|Pt|Sv|Zh)*?\)\s*\(Unl\)\.zip"
#(USA, Australia) <Anything Except (Alt ) or (Rev ) or (Demo)>.zip
,"^(?=.*?\(USA,\s*Australia\))((?!\(Alt\s*[A-Z0-9]{0,2}\)|\(Rev\s*[A-Z0-9\.]{0,4}\)|\(Demo\)).)*$"
#(USA, Korea).zip
,"\(USA,\s*Korea\)\.zip"
#(USA, Korea) (Unl).zip
,"\(USA,\s*Korea\)\s*\(Unl\)\.zip"
#(USA, Korea) (En,*).zip
,"\(USA,\s*Korea\)\s*\(En(,|\+|Ca|Da|De|En|Es|Fi|Fr|It|Ja|Nl|No|Pl|Pt|Sv|Zh)*?\)\.zip"
#(USA, Korea) (En,*) (Unl).zip
,"\(USA,\s*Korea\)\s*\(En(,|\+|Ca|Da|De|En|Es|Fi|Fr|It|Ja|Nl|No|Pl|Pt|Sv|Zh)*?\)\s*\(Unl\)\.zip"
#(USA, Korea) <Anything Except (Alt ) or (Rev ) or (Demo)>.zip
,"^(?=.*?\(USA,\s*Korea\))((?!\(Alt\s*[A-Z0-9]{0,2}\)|\(Rev\s*[A-Z0-9\.]{0,4}\)|\(Demo\)).)*$"
#(USA) (Rev #)
,"^(?=.*?\(USA\))(?=.*?\(Rev\s*[0-9\.]{0,4}\)).*$"
#(USA) (Rev A)
,"^(?=.*?\(USA\))(?=.*?\(Rev\s*[A-Z]{0,4}\)).*$"
#(USA) (Rev #A)
,"^(?=.*?\(USA\))(?=.*?\(Rev\s*[A-Z0-9\.]{0,4}\)).*$"
#(USA) (Alt) OR (Alternate)
,"^(?=.*?\(USA\))(?=.*?(\(Alt\)|\(Alternate\))).*$"
#(USA) (Alt #)
,"^(?=.*?\(USA\))(?=.*?\(Alt\s*[A-Z0-9]{1,2}\)).*$"
#(USA)
,"\(USA\)"
#(USA, Europe)
,"\(USA,\s*Europe\)"
#(Japan, USA)
,"\(Japan,\s*USA\)"
#(USA, Asia)
,"\(USA,\s*Asia\)"
#(USA, Australia)
,"\(USA,\s*Australia\)"
#(USA, Korea)
,"\(USA,\s*Korea\)"
#(*USA*)
,"\((.*?)USA(.*?)\)"
#---------------------------------------
#---WORLD PREFERRED ORDER---
#---------------------------------------
#(World).zip
"\(World\)\.zip"
#(World) (Unl).zip
,"\(World\)\s*\(Unl\)\.zip"
#(World) (En,*).zip
,"\(World\)\s*\(En(,|\+|Ca|Da|De|En|Es|Fi|Fr|It|Ja|Nl|No|Pl|Pt|Sv|Zh)*?\)\.zip"
#(World) (En,*) (Unl).zip
,"\(World\)\s*\(En(,|\+|Ca|Da|De|En|Es|Fi|Fr|It|Ja|Nl|No|Pl|Pt|Sv|Zh)*?\)\s*\(Unl\)\.zip"
#(World) <Anything Except (Alt ) or (Rev ) or (Demo)>.zip
,"^(?=.*?\(World\))((?!\(Alt\s*[A-Z0-9]{0,2}\)|\(Rev\s*[A-Z0-9\.]{0,4}\)|\(Demo\)).)*$"
#(World) (Rev #)
,"^(?=.*?\(World\))(?=.*?\(Rev\s*[0-9\.]{0,4}\)).*$"
#(World) (Rev A)
,"^(?=.*?\(World\))(?=.*?\(Rev\s*[A-Z]{0,4}\)).*$"
#(World) (Rev #A)
,"^(?=.*?\(World\))(?=.*?\(Rev\s*[A-Z0-9\.]{0,4}\)).*$"
#(World) (Alt) OR (Alternate)
,"^(?=.*?\(World\))(?=.*?(\(Alt\)|\(Alternate\))).*$"
#(World) (Alt #)
,"^(?=.*?\(World\))(?=.*?\(Alt\s*[A-Z0-9]{1,2}\)).*$"
#(World)
,"\(World\)"
#(*World*)
,"\((.*?)World(.*?)\)"
#---------------------------------------
#---EUROPE PREFERRED ORDER---
#---------------------------------------
#(Europe).zip
"\(Europe\)\.zip"
#(Europe) (Unl).zip
,"\(Europe\)\s*\(Unl\)\.zip"
#(Europe) (En,*).zip
,"\(Europe\)\s*\(En(,|\+|Ca|Da|De|En|Es|Fi|Fr|It|Ja|Nl|No|Pl|Pt|Sv|Zh)*?\)\.zip"
#(Europe) (En,*) (Unl).zip
,"\(Europe\)\s*\(En(,|\+|Ca|Da|De|En|Es|Fi|Fr|It|Ja|Nl|No|Pl|Pt|Sv|Zh)*?\)\s*\(Unl\)\.zip"
#(Europe) <Anything Except (Alt ) or (Rev ) or (Demo)>.zip
,"^(?=.*?\(Europe\))((?!\(Alt\s*[A-Z0-9]{0,2}\)|\(Rev\s*[A-Z0-9\.]{0,4}\)|\(Demo\)).)*$"
#(Japan, Europe).zip
,"\(Japan,\s*Europe\)\.zip"
#(Japan, Europe) (Unl).zip
,"\(Japan,\s*Europe\)\s*\(Unl\)\.zip"
#(Japan, Europe) (En,*).zip
,"\(Japan,\s*Europe\)\s*\(En(,|\+|Ca|Da|De|En|Es|Fi|Fr|It|Ja|Nl|No|Pl|Pt|Sv|Zh)*?\)\.zip"
#(Japan, Europe) (En,*) (Unl).zip
,"\(Japan,\s*Europe\)\s*\(En(,|\+|Ca|Da|De|En|Es|Fi|Fr|It|Ja|Nl|No|Pl|Pt|Sv|Zh)*?\)\s*\(Unl\)\.zip"
#(Japan, Europe) <Anything Except (Alt ) or (Rev ) or (Demo)>.zip
,"^(?=.*?\(Japan,\s*Europe\))((?!\(Alt\s*[A-Z0-9]{0,2}\)|\(Rev\s*[A-Z0-9\.]{0,4}\)|\(Demo\)).)*$"
#(Europe) (Rev #)
,"^(?=.*?\(Europe\))(?=.*?\(Rev\s*[0-9\.]{0,4}\)).*$"
#(Europe) (Rev A)
,"^(?=.*?\(Europe\))(?=.*?\(Rev\s*[A-Z]{0,4}\)).*$"
#(Europe) (Rev #A)
,"^(?=.*?\(Europe\))(?=.*?\(Rev\s*[A-Z0-9\.]{0,4}\)).*$"
#(Europe) (Alt) OR (Alternate)
,"^(?=.*?\(Europe\))(?=.*?(\(Alt\)|\(Alternate\))).*$"
#(Europe) (Alt #)
,"^(?=.*?\(Europe\))(?=.*?\(Alt\s*[A-Z0-9]{1,2}\)).*$"
#(Europe)
,"\(Europe\)"
#(*Europe*)
,"\((.*?)Europe(.*?)\)"
#---------------------------------------
#---JAPAN PREFERRED ORDER---
#---------------------------------------
#(Japan).zip
"\(Japan\)\.zip"
#(Japan) (Unl).zip
,"\(Japan\)\s*\(Unl\)\.zip"
#(Japan) (En,*).zip
,"\(Japan\)\s*\(En(,|\+|Ca|Da|De|En|Es|Fi|Fr|It|Ja|Nl|No|Pl|Pt|Sv|Zh)*?\)\.zip"
#(Japan) (En,*) (Unl).zip
,"\(Japan\)\s*\(En(,|\+|Ca|Da|De|En|Es|Fi|Fr|It|Ja|Nl|No|Pl|Pt|Sv|Zh)*?\)\s*\(Unl\)\.zip"
#(Japan) <Anything Except (Alt ) or (Rev ) or (Demo)>.zip
,"^(?=.*?\(Japan\))((?!\(Alt\s*[A-Z0-9]{0,2}\)|\(Rev\s*[A-Z0-9\.]{0,4}\)|\(Demo\)).)*$"
#(Japan, Korea).zip
,"\(Japan,\s*Korea\)\.zip"
#(Japan, Korea) (Unl).zip
,"\(Japan,\s*Korea\)\s*\(Unl\)\.zip"
#(Japan, Korea) (En,*).zip
,"\(Japan,\s*Korea\)\s*\(En(,|\+|Ca|Da|De|En|Es|Fi|Fr|It|Ja|Nl|No|Pl|Pt|Sv|Zh)*?\)\.zip"
#(Japan, Korea) (En,*) (Unl).zip
,"\(Japan,\s*Korea\)\s*\(En(,|\+|Ca|Da|De|En|Es|Fi|Fr|It|Ja|Nl|No|Pl|Pt|Sv|Zh)*?\)\s*\(Unl\)\.zip"
#(Japan, Korea) <Anything Except (Alt ) or (Rev ) or (Demo)>.zip
,"^(?=.*?\(Japan,\s*Korea\))((?!\(Alt\s*[A-Z0-9]{0,2}\)|\(Rev\s*[A-Z0-9\.]{0,4}\)|\(Demo\)).)*$"
#(Japan) (Rev #)
,"^(?=.*?\(Japan\))(?=.*?\(Rev\s*[0-9\.]{0,4}\)).*$"
#(Japan) (Rev A)
,"^(?=.*?\(Japan\))(?=.*?\(Rev\s*[A-Z]{0,4}\)).*$"
#(Japan) (Rev #A)
,"^(?=.*?\(Japan\))(?=.*?\(Rev\s*[A-Z0-9\.]{0,4}\)).*$"
#(Japan) (Alt) OR (Alternate)
,"^(?=.*?\(Japan\))(?=.*?(\(Alt\)|\(Alternate\))).*$"
#(Japan) (Alt #)
,"^(?=.*?\(Japan\))(?=.*?\(Alt\s*[A-Z0-9]{1,2}\)).*$"
#(Japan)
,"\(Japan\)"
#(*Japan*)
,"\((.*?)Japan(.*?)\)"
#---------------------------------------
#---ALL ELSE FAILED PREFERRED ORDER---
#---------------------------------------
#(Unknown)
,"\(Unknown\)"
)
'@
Return $DefaultFilters
}
End
{
#Nothing to Do Here
}
}
Function Write-Out
{
<#
.SYNOPSIS
Write output to console and/or log file. Supports multiple foreground and background colors on a single line and
advanced options to insert lines, spaces, or tabs before or after the text as well as timestamps.
.DESCRIPTION
Uses Write-Host to output color text to the console, and supports using multiple foreground and background colors
on a single line. Uses Set-Content and Add-Content to output to a file.
It works by accepting strings as an array and then you can assign the foreground or background colors by passing
them as arrays for the matching text. It also accepts Default which allows you skip specifying a color and use the
default.
This function requires Powershell 4.0 to support the alias attribute in the function.
.PARAMETER Text
Optional. Array of strings to write to console/log. If you do not need to use multiple colors on a single line you can pass a single string instead of an array of strings. Otherwise, if you need to multiple colors on a single line pass an array of strings and associated colors using -ForegroundColor, -BackgroundColor, -ForegroundColorDefault, or -BackgroundColorDefault.
.PARAMETER ForegroundColor
Optional. Array of foreground Colors to write to console. Default means the ForegroundColorDefault value is used.
Valid Colors: Default, Black, DarkBlue, DarkGreen, DarkCyan, DarkRed, DarkMagenta, DarkYellow, Gray, DarkGray, Blue, Green, Cyan, Red, Magenta, Yellow, White
.PARAMETER ForegroundColorDefault
Optional. Default foreground color to write to console. Default is set to white.
Valid Colors: Black, DarkBlue, DarkGreen, DarkCyan, DarkRed, DarkMagenta, DarkYellow, Gray, DarkGray, Blue, Green, Cyan, Red, Magenta, Yellow, White
.PARAMETER BackgroundColor
Optional. Array of background colors to write to console. Default means the BackgroundColorDefault value is used.
Valid Colors: Default, Black, DarkBlue, DarkGreen, DarkCyan, DarkRed, DarkMagenta, DarkYellow, Gray, DarkGray, Blue, Green, Cyan, Red, Magenta, Yellow, White
.PARAMETER BackgroundColorDefault
Optional. Default background color to write to console. Default is none.
Valid Colors: Default, Black, DarkBlue, DarkGreen, DarkCyan, DarkRed, DarkMagenta, DarkYellow, Gray, DarkGray, Blue, Green, Cyan, Red, Magenta, Yellow, White
.PARAMETER PreLine
Optional. Add blank lines before your text. Default is 0.
.PARAMETER PreSpace
Optional. Add spaces before your text. Default is 0.
.PARAMETER PreTab
Optional. Add Tabs before your text. Default is 0.
.PARAMETER TimeStampFormat
Optional. Format used for time stamps. Default is 'yyyy-MM-dd HH:mm:ss'
.PARAMETER TimeStamp
Optional. Adds time stamp in square brackets before your text.
.PARAMETER ClearHost
Optional. Clear the console before your text.
.PARAMETER PostLine
Optional. Add blank lines after your text. Default is 0.
.PARAMETER PostSpace
Optional. Add spaces after your text. Default is 0.
.PARAMETER PostTab
Optional. Add tabs after your text. Default is 0.
.PARAMETER NoNewLine
Optional. Do not add a new line after your text and optional post text options. Default is to add a new line.
.PARAMETER LogFile
Optional. Absolute or relative path of the log file.
.PARAMETER Overwrite
Optional. Ovewrite the log file. Default is to append to the log file.
.INPUTS
Parameters above
.OUTPUTS
None
.NOTES
Author: Brian Steinmeyer
URL: http://sigkillit.com/
Created: 4/18/2020
Version 1.3
- Added LogOnly Option for only writing text to a log file
Version 1.2
- Set Text, ForegroundColor, and BackgroundColor to default value of @() to fix errors checking counts in some circumstances
- Fixed an issue where ForegroundColorDefault and BackgroundColorDefault were not working properly in some circumstances
- Added Requires -Version 4.0
Version 1.1
- Completely rewrote the "Main Text" section
- Added "Default" as a color option, which allows you to use the default values for foreground/background
- Useful when you want to specify a backgroundcolor in certain parts of a line like the middle
- Ex: Write-Out -Text "How to ","highlight ","the middle text" -BackgroundColor Default,Yellow,Default
Version: 1.0
- Initial Creation inspired by PSWriteColor (https://github.com/EvotecIT/PSWriteColor)
- Improved upon by switching Foreground and Background Colors to default values if colors are not specifid for all strings.
Will also ignore extra colors if more colors are specified than strings specified.
.EXAMPLE
Write-Out -Text "Start with Red Text ","Then Switch to Blue Text ","Now Magenta" -ForegroundColor Red,Blue,Magenta
.EXAMPLE
Write-Out -Text "White on Black ","Black on White ","Dark Cyan on Cyan ","Yellow on Green ","Default Color" -ForegroundColor White,Black,DarkCyan,Yellow -BackgroundColor Black,White,Cyan,Green
.EXAMPLE
Write-Out -Text "Make this"," entire line"," the same color by setting defaults" -ForegroundColorDefault Yellow -BackgroundColorDefault Magenta
.EXAMPLE
Write-Out -Text "Add a blank line and two tabs ","before ","my text" -ForegroundColor Green,Cyan,White -PreLine 1 -PreTab 2
.EXAMPLE
Write-Out -Text "Add two blank ","lines ","after my text" -ForegroundColor White,Green,White -PostLine 2
.EXAMPLE
Write-Out -Text "Add 3 spaces before my text" -ForegroundColor Gray -Prespace 3
.EXAMPLE
Write-Out -Text "White text and a tab after" -ForegroundColor White -NoNewLine -PostTab 1
Write-Out -Text "Black text on Yellow ","and then back to white" -ForegroundColor Black,White -BackgroundColor Yellow
.EXAMPLE
Write-Out -Text "An easy way to ","highlight ","text in the middle" -BackgroundColor Default,Yellow
.EXAMPLE
Write-Out -Text "You can even add a ","time stamp ","before your output" -ForegroundColor White,Green,White -TimeStamp -PreLine 3
.EXAMPLE
Write-Out -Text "You can change the ","time stamp format" -ForegroundColor White,Yellow -TimeStamp -TimeStampFormat "dd-MM-yyy HH:mm" -PreLine 1 -PostLine 1
.EXAMPLE
Write-Out -Text "An"," Error"," occurred let's write overwrite/create a new log file" -ForegroundColor White,Red,White -TimeStamp -LogFile "script.log" -Overwrite
.EXAMPLE
Write-Out -Text "Now you can ","Append ","this line to your log file" -ForegroundColor Cyan,Magenta -TimeStamp -LogFile "script.log"
#>
[CmdletBinding()]
Param (
[Parameter(Mandatory=$false)]
[AllowEmptyString()]
[alias ('T')]
[String[]]
$Text = @(),
[Parameter(Mandatory=$false)]
[ValidateSet("Default","Black","DarkBlue","DarkGreen","DarkCyan","DarkRed","DarkMagenta","DarkYellow","Gray","DarkGray","Blue","Green","Cyan","Red","Magenta","Yellow","White")]
[alias ('FGC', 'FC')]
[string[]]
$ForegroundColor = @(),
[Parameter(Mandatory=$false)]
[ValidateSet("Default","Black","DarkBlue","DarkGreen","DarkCyan","DarkRed","DarkMagenta","DarkYellow","Gray","DarkGray","Blue","Green","Cyan","Red","Magenta","Yellow","White")]
[alias ('FGCD', 'FCD')]
[string]
$ForegroundColorDefault = [ConsoleColor]::White,
[Parameter(Mandatory=$false)]
[ValidateSet("Default","Black","DarkBlue","DarkGreen","DarkCyan","DarkRed","DarkMagenta","DarkYellow","Gray","DarkGray","Blue","Green","Cyan","Red","Magenta","Yellow","White")]
[alias ('BGC', 'BC')]
[String[]]
$BackgroundColor = @(),
[Parameter(Mandatory=$false)]
[ValidateSet("Default","Black","DarkBlue","DarkGreen","DarkCyan","DarkRed","DarkMagenta","DarkYellow","Gray","DarkGray","Blue","Green","Cyan","Red","Magenta","Yellow","White")]
[alias ('BGCD', 'BCD')]
[string]
$BackgroundColorDefault = "Default",
[Parameter(Mandatory=$false)]
[int]
$PreLine = 0,
[Parameter(Mandatory=$false)]
[int]
$PreSpace = 0,
[Parameter(Mandatory=$false)]
[int]
$PreTab = 0,
[Parameter(Mandatory=$false)]
[Alias('TSF', 'TS')]
[string]
$TimeStampFormat = 'yyyy-MM-dd HH:mm:ss',
[Parameter(Mandatory=$false)]
[switch]
$TimeStamp,
[Parameter(Mandatory=$false)]
[switch]
$ClearHost,
[Parameter(Mandatory=$false)]
[int]
$PostLine = 0,
[Parameter(Mandatory=$false)]
[int]
$PostSpace = 0,
[Parameter(Mandatory=$false)]
[int]
$PostTab = 0,
[Parameter(Mandatory=$false)]
[switch]
$NoNewLine = $false,
[Parameter(Mandatory=$false)]
[alias ('Log', 'L')]
[string]
$LogFile = '',
[Parameter(Mandatory=$false)]
[switch]
$LogOnly = $false,
[Parameter(Mandatory=$false)]
[switch]
$Overwrite = $false
)
Begin
{
#Nothing to Do Here
}
Process
{
#Optional - Do Not Write to ConsoleColor
If (!($LogOnly))
{
#Optional - Prefix Text
If ($ClearHost) { Clear-Host }
If ($PreLine -gt 0) { For ($i = 0; $i -lt $PreLine; $i++) { Write-Host -Object "`n" -NoNewline } } # Add empty line(s) before Main text
If ($PreSpace -gt 0) { For ($i = 0; $i -lt $PreSpace; $i++) { Write-Host -Object " " -NoNewLine } } # Add Tab(s) before Main text
If ($PreTab -gt 0) { For ($i = 0; $i -lt $PreTab; $i++) { Write-Host -Object "`t" -NoNewLine } } # Add Space(s) before Main text
If ($TimeStamp) { Write-Host -Object "[$([datetime]::Now.ToString($TimeStampFormat))]" -NoNewline } # Add Timestamp before Main Text
#MAIN TEXT
If (($Text.Count -gt 0) -AND ($ForegroundColor.Count -eq 0) -AND ($BackgroundColor.Count -eq 0))
{
#Text Only Specified
For ($i = 0; $i -lt $Text.Count; $i++)
{
If ($BackgroundColorDefault -eq "Default")
{
Write-Host $Text[$i] -ForegroundColor $ForegroundColorDefault -NoNewLine
}
Else
{
Write-Host $Text[$i] -ForegroundColor $ForegroundColorDefault -BackgroundColor $BackgroundColorDefault -NoNewLine
}
}
}
ElseIf (($Text.Count -gt 0) -AND ($ForegroundColor.Count -gt 0) -AND ($BackgroundColor.Count -eq 0))
{
#Text and ForegroundColor Specified
For ($i = 0; $i -lt $Text.Count; $i++)
{
If ($ForegroundColor.Count -le $i) { $ForegroundColor += $ForegroundColorDefault } #ForegroundColor Not Specified Set to Default
If ($ForegroundColor[$i] -eq "Default") { $ForegroundColor[$i] = $ForegroundColorDefault }
If ($BackgroundColorDefault -eq "Default")
{
Write-Host $Text[$i] -ForegroundColor $ForegroundColor[$i] -NoNewLine
}
Else
{
Write-Host $Text[$i] -ForegroundColor $ForegroundColor[$i] -BackgroundColor $BackgroundColorDefault -NoNewLine
}
}
}
ElseIf (($Text.Count -gt 0) -AND ($ForegroundColor.Count -eq 0) -AND ($BackgroundColor.Count -gt 0))
{
#Text and BackgroundColor Specified
For ($i = 0; $i -lt $Text.Count; $i++)
{
If ($BackgroundColor.Count -le $i) { $BackgroundColor += $BackgroundColorDefault } #BackgroundColor Not Specified Set to Default
If ($BackgroundColor[$i] -eq "Default")
{
If ($BackgroundColorDefault -eq "Default")
{
Write-Host $Text[$i] -ForegroundColor $ForegroundColorDefault -NoNewLine
}
Else
{
Write-Host $Text[$i] -ForegroundColor $ForegroundColorDefault -BackgroundColor $BackgroundColorDefault -NoNewLine
}
}
Else
{
Write-Host $Text[$i] -ForegroundColor $ForegroundColorDefault -BackgroundColor $BackgroundColor[$i] -NoNewLine
}
}
}
ElseIf (($Text.Count -gt 0) -AND ($ForegroundColor.Count -gt 0) -AND ($BackgroundColor.Count -gt 0))
{
#Text, ForegroundColor, and BackgroundColor Specified (FAILS NOT WRITING DEFAULT)
For ($i = 0; $i -lt $Text.Count; $i++)
{
If ($ForegroundColor.Count -le $i) { $ForegroundColor += $ForegroundColorDefault } #ForegroundColor Not Specified Set to Default
If ($BackgroundColor.Count -le $i) { $BackgroundColor += $BackgroundColorDefault } #BackgroundColor Not Specified Set to Default
If ($ForegroundColor[$i] -eq "Default") { $ForegroundColor[$i] = $ForegroundColorDefault }
If ($BackgroundColor[$i] -eq "Default")
{
If ($BackgroundColorDefault -eq "Default")
{
Write-Host $Text[$i] -ForegroundColor $ForegroundColor[$i] -NoNewLine
}
Else
{
Write-Host $Text[$i] -ForegroundColor $ForegroundColor[$i] -BackgroundColor $BackgroundColorDefault -NoNewLine
}
}
Else
{
Write-Host $Text[$i] -ForegroundColor $ForegroundColor[$i] -BackgroundColor $BackgroundColor[$i] -NoNewLine
}
}
}
Else
{
#No Text, ForegroundColor, or BackgroundColor Specified ($Text.Count -eq 0) -AND ($ForegroundColor.Count -eq 0) -AND ($BackgroundColor.Count -eq 0)
}
#Post Text
If ($PostSpace -gt 0) { for ($i = 0; $i -lt $PostSpace; $i++) { Write-Host -Object " " -NoNewLine } } # Add Tab(s) after Main text
If ($PostTab -gt 0) { for ($i = 0; $i -lt $PostTab; $i++) { Write-Host -Object "`t" -NoNewLine } } # Add Space(s) after Main text
If ($PostLine -gt 0) { for ($i = 0; $i -lt $PostLine; $i++) { Write-Host -Object "`n" -NoNewline } } # Add empty line(s) after Main text
If ($NoNewLine) { Write-Host -NoNewline } else { Write-Host } # Add New Line after Main Text Unless NoNewLine is Supplied
}
#Log File
$TextToWrite = "" #Build Text to Write to Log File
If ($PreLine -gt 0) { For ($i = 0; $i -lt $PreLine; $i++) { $TextToWrite += "`n" } } # Add empty line(s) before Main text
If ($PreSpace -gt 0) { For ($i = 0; $i -lt $PreSpace; $i++) { $TextToWrite += " " } } # Add Tab(s) before Main text
If ($PreTab -gt 0) { For ($i = 0; $i -lt $PreTab; $i++) { $TextToWrite += "`t" } } # Add Space(s) before Main text
If ($TimeStamp) { $TextToWrite += "[$([datetime]::Now.ToString($TimeStampFormat))]" } # Add Timestamp before Main Text
If ($Text.Count -gt 0) { For ($i = 0; $i -lt $Text.Count; $i++) { $TextToWrite += $Text[$i] } } #Add Main Text
If ($PostSpace -gt 0) { for ($i = 0; $i -lt $PostSpace; $i++) { $TextToWrite += " " } } # Add Tab(s) after Main text
If ($PostTab -gt 0) { for ($i = 0; $i -lt $PostTab; $i++) { $TextToWrite += "`t" } } # Add Space(s) after Main text
If ($PostLine -gt 0) { for ($i = 0; $i -lt $PostLine; $i++) { $TextToWrite += "`n" } } # Add empty line(s) after Main text
If ($LogFile -eq "")
{
#No LogFile Specified - Skip
}
ElseIf(!(Test-Path -Path $LogFile))
{
#Create Log File If Does Not Exist
If ($NoNewLine)
{
$nf = New-Item -Path $LogFile -type file -force -Value $TextToWrite
}
Else
{
$nf = New-Item -Path $LogFile -type file -force -Value $TextToWrite`r`n
}
}
Else
{
#Log File Exists
If($Overwrite)
{
#Overwrite Log File
If ($NoNewLine)
{
Set-Content -Path $LogFile -Value $TextToWrite -NoNewline
}
Else
{
Set-Content -Path $LogFile -Value $TextToWrite
}
}
Else
{
#Append Log File
Try {
If ($NoNewLine)
{
Add-Content -Path $LogFile -Value $TextToWrite -ErrorAction Stop -NoNewline
}
Else
{
Add-Content -Path $LogFile -Value $TextToWrite -ErrorAction Stop
}
} Catch {
Start-Sleep -s 3
If ($NoNewLine)
{
Add-Content -Path $LogFile -Value $TextToWrite -NoNewline
}
Else
{
Add-Content -Path $LogFile -Value $TextToWrite
}
}
}
}
}
End
{
#Nothing to Do Here
}
}
Main