Find RetroPie Unscraped Data

This is intended to be used as the supplemental script (3_CheckXML.ps1) to be used in conjunction with the 1_Clean-NoIntroRoms.ps1 and 2_CompareFolderResults.ps1 scripts. This script allows you check missing scraped data in RetroPie by examining the gamelist.xml file for each game system on you RetroPie. This can save you HOURS of time manually checking for missing ROM scraped data.

Global Variable Definitions:

  • All documentation is now centrally contained in the readme.txt included in the download. Please refer to that document for definitions on the variables as well as their default values.
#3_CheckXML.ps1
$global:scriptName = $PSCommandPath
$global:scriptVersion = "v6.0"
$global:GameListRoot = "\\retropie\configs\all\emulationstation\gamelists\"
$global:romSplitstr = ""
$global:romFilterDirectory = (Split-Path -Path $PSCommandPath -Parent) + "\filters\"
$global:FindDuplicates = $true
$global:IgnoreMulticartDuplicates = $true
$global:MultiCartExceptions = @()
$global:runNoIntroRoms = $true
$global:runCustomRoms = $false
$global:ValidateVerbose = $false
$global:logFile = (Split-Path -Path $PSCommandPath -Parent) + "\logs\" + (Split-Path -Path $PSCommandPath.Replace(".ps1",".log") -Leaf)
$global:logOverwrite = $true
$global:ValidateData = [ordered]@{
	"path" = $false
	"name" = $true
	"cover" = $false
	"image" = $true
	"marquee" = $false
	"video" = $false
	"rating" = $false
	"desc" = $true
	"releasedate" = $false
	"developer" = $false
	"publisher" = $false
	"genre" = $false
	"players" = $false
	"kidgame" = $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"
}
$global:romCustomHashTable = [ordered]@{
	#RetroPieDirName = CustomDirName
	"amstradcpc" = "Amstrad - CPC"
	"apple2" = "Apple_2_TOSEC_2012_04_23"
	"atari800" = "Atari_8_bit_TOSEC_2012_04_23"
	"c64" = "c64"
	"coco" = "coco"
	"dragon32" = "Dragon_Data_Dragon_TOSEC_2012_04_23"
	"intellivision" = "Mattel_Intellivision _TOSEC-v2014-01-18_CM"
	"neogeo" = "neo-geo-mvs-romset"
	"trs-80" = "Tandy Radio Shack TRS-80 Color Computer - Games"
	"zmachine" = "Infocom_Z-Machine_TOSEC_2012_04_23"
	"zxspectrum" = "zx-spectrum-tosec-set-v-2020-02-18-lady-eklipse"
}
#Output Color Variables
$global:colorMain = "Green"
$global:colorSub1 = "DarkGreen"
$global:colorSub2 = "Cyan"
$global:colorSub3 = "DarkRed"
$global:colorOk = "DarkCyan"
$global:colorWarn = "Yellow"
$global:colorError = "Red"



Function Main()
{
	#Output Color Variables
	$global:colorMain = "Green"
	$global:colorSub1 = "DarkGreen"
	$global:colorSub2 = "Cyan"
	$global:colorOk = "DarkCyan"
	$global:colorWarn = "Yellow"
	$global:colorError = "Red"

	#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 -NoNewLine -LogFile $global:logFile -Overwrite
	}
	Else 
	{
		Write-Out -NoNewLine -LogFile $global:logFile
	}
	
	$ScriptStart = (Get-Date)
	Write-Out -ForegroundColor $global:colorMain -Text "****************************************************************" -LogFile $global:logFile
	Write-Out -Text "SECTION 1: INITIALIZE" -ForegroundColor $global:colorMain -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 "* Game List Root              : $($global:GameListRoot)" -LogFile $global:logFile
	If ([string]::IsNullOrEmpty($global:romSplitstr))
	{
		Write-Out -ForegroundColor $global:colorMain -Text "* Manual romSplitstr          : Not Set" -LogFile $global:logFile
	}
	Else
	{
		Write-Out -ForegroundColor $global:colorMain -Text "* Manual romSplitstr          : $($global:romSplitstr)" -LogFile $global:logFile
	}
	Write-Out -ForegroundColor $global:colorMain -Text "* ROM Filter Dir              : $($global:romFilterDirectory)" -LogFile $global:logFile
	Write-Out -ForegroundColor $global:colorMain -Text "* Find Duplicates             : $($global:FindDuplicates)" -LogFile $global:logFile
	Write-Out -ForegroundColor $global:colorMain -Text "* Ignore Multicart Exceptions : $($global:IgnoreMulticartDuplicates)" -LogFile $global:logFile
	If ($global:MultiCartExceptions.Count -le 0)
	{
		Write-Out -ForegroundColor $global:colorMain -Text "* Manual Multicart Exceptions : Not Set" -LogFile $global:logFile
	}
	Else
	{
		Write-Out -ForegroundColor $global:colorMain -Text "* Manual Multicart Exceptions : $($global:MultiCartExceptions -Join "`n`t`t`t`t")" -LogFile $global:logFile
	}
	Write-Out -ForegroundColor $global:colorMain -Text "* Check No-Intro ROMs         : $($global:runNoIntroRoms)" -LogFile $global:logFile
	Write-Out -ForegroundColor $global:colorMain -Text "* Check Custom ROMs           : $($global:runCustomRoms)" -LogFile $global:logFile
	Write-Out -ForegroundColor $global:colorMain -Text "* Validate Verbose            : $($global:ValidateVerbose)" -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 "* Start Time                  : $($ScriptStart)" -LogFile $global:logFile
	Write-Out -ForegroundColor $global:colorMain -Text "****************************************************************" -LogFile $global:logFile
	Write-Out -ForegroundColor $global:colorSub1 -Text "Validating Global Variables" -LogFile $global:logFile
	Write-Out -ForegroundColor $global:colorSub1 -Text "================================================================" -LogFile $global:logFile
	If (!(Validate-Container -Name '$global:GameListRoot' -Path ([ref]$global:GameListRoot) -Log $global:logFile -EndsWithBackslash)) { Write-Out -ForegroundColor $global:colorError -Text "EXIT SCRIPT!!!" -LogFile $global:logFile; EXIT }
	If (!(Validate-Container -Name '$global:romFilterDirectory' -Path ([ref]$global:romFilterDirectory) -Log $global:logFile -EndsWithBackslash)) { Write-Out -ForegroundColor $global:colorError -Text "EXIT SCRIPT!!!" -LogFile $global:logFile; EXIT }
	$Results = [ordered]@{}
	
	$StartNoIntro = (Get-Date)
	Write-Out -PreLine 3 -ForegroundColor $global:colorMain -Text "****************************************************************" -LogFile $global:logFile
	Write-Out -ForegroundColor $global:colorMain -Text "SECTION 2: CHECK GAMESLIST XML FOR NO-INTRO ROMS" -LogFile $global:logFile
	Write-Out -ForegroundColor $global:colorMain -Text "****************************************************************" -LogFile $global:logFile
	$TempVD = $global:ValidateData
	If ($global:ValidateVerbose) { @($TempVD.GetEnumerator()) | ? {$_.Value -eq $false} | % { $TempVD[$_.Key]=$true} }
	$ArgumentHash = @{
		RomHashTable = $global:romNoIntroHashTable
		GameList = $global:GameListRoot
		ValidateData = $TempVD
		Splitstr = $global:romSplitstr
		Filters = $global:romFilterDirectory
		FindDuplicates = $global:FindDuplicates
		IgnoreMulticartDuplicates = $global:IgnoreMulticartDuplicates
		Log = $global:logFile
	}
	If (($global:MultiCartExceptions.Count -gt 0))
	{
		$ArgumentHash.Add("MultiCartExceptions", $global:MultiCartExceptions)
	}
	If ($global:runNoIntroRoms)
	{
		If ($global:romNoIntroHashTable.Count -eq 0)
		{
			Write-Out -ForegroundColor $global:colorWarn -Text "Warning: Nothing is in romNoIntroHashTable (All sytems are probably commented out in global hashtable)" -LogFile $global:logFile
			$Results.Add("No-Intro ROMs",@())
		}
		Else
		{
			$Results.Add("No-Intro ROMs",(Check-GamesListXML @ArgumentHash))
		}
	}
	Else
	{
		Write-Out -ForegroundColor $global:colorWarn -Text "Skip - Global Variable runNoIntroRoms set to False" -LogFile $global:logFile
		$Results.Add("No-Intro ROMs",@())
	}
	$EndNoIntro = (Get-Date)
	
	
	$StartCustom = (Get-Date)
	Write-Out -PreLine 2 -ForegroundColor $global:colorMain -Text "****************************************************************" -LogFile $global:logFile
	Write-Out -ForegroundColor $global:colorMain -Text "SECTION 3: CHECK GAMESLIST XML FOR CUSTOM ROMS" -LogFile $global:logFile
	Write-Out -ForegroundColor $global:colorMain -Text "****************************************************************" -LogFile $global:logFile
	$TempVD = $global:ValidateData
	If ($global:ValidateVerbose) { @($TempVD.GetEnumerator()) | ? {$_.Value -eq $false} | % { $TempVD[$_.Key]=$true} }
	$ArgumentHash = @{
		RomHashTable = $global:romCustomHashTable
		GameList = $global:GameListRoot
		ValidateData = $TempVD
		Splitstr = $global:romSplitstr
		Filters = $global:romFilterDirectory
		FindDuplicates = $global:FindDuplicates
		IgnoreMulticartDuplicates = $global:IgnoreMulticartDuplicates
		Log = $global:logFile
	}
	If (($global:MultiCartExceptions.Count -gt 0))
	{
		$ArgumentHash.Add("MultiCartExceptions", $global:MultiCartExceptions)
	}
	If ($global:runCustomRoms)
	{
		If ($global:romCustomHashTable.Count -eq 0)
		{
			Write-Out -ForegroundColor $global:colorWarn -Text "Warning: Nothing is in romCustomHashTable (All sytems are probably commented out in global hashtable)" -LogFile $global:logFile
			$Results.Add("Custom ROMs",@())
		}
		Else
		{
			$Results.Add("Custom ROMs",(Check-GamesListXML @ArgumentHash))
		}
	}
	Else
	{
		Write-Out -ForegroundColor $global:colorWarn -Text "Skip - Global Variable runCustomRoms set to False" -LogFile $global:logFile
		$Results.Add("Custom ROMs",@())
	}
	$EndCustom = (Get-Date)
	
	
	
	Write-Out -PreLine 2 -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
	ForEach ($R in $Results.Keys)
	{
		Write-Out -Text "* RESULTS $($R.ToUpper())" -ForegroundColor $global:colorMain -LogFile $LogFiles
		Write-Out -Text "* **************************************************************" -ForegroundColor $global:colorMain -LogFile $LogFiles
		If ($Results[$R].Count -eq 0) 
		{
			Write-Out -Text "Skip - Nothing Was Processed!" -ForegroundColor $global:colorWarn -PostLine 1 -LogFile $LogFiles
		}
		ForEach ($G in $Results[$R])
		{
			Write-Out -Text "* $($G.GameSystem):" -ForegroundColor $global:colorMain -LogFile $LogFiles
			If ($G.GameListExist -eq $false)
			{
				Write-Out -Text "*  ","ERROR - XML File Not Exist: ($($G.GameList))" -ForegroundColor $global:colorMain,$global:colorError -LogFile $LogFiles
				Write-Out -Text "* -Total Games     : ","N/A" -ForegroundColor $global:colorMain,$global:colorError -LogFile $LogFiles
				Write-Out -Text "* -ROMs Not Scraped: ","N/A" -ForegroundColor $global:colorMain,$global:colorError -LogFile $LogFiles
				Write-Out -Text "* -Missing Data    : ","N/A" -ForegroundColor $global:colorMain,$global:colorError -LogFile $LogFiles
				Write-Out -Text "* -Duplicate ROMs  : ","N/A" -ForegroundColor $global:colorMain,$global:colorError -LogFile $LogFiles
			}
			Else 
			{
				Write-Out -Text "* -Total Games     : $($G.Games.Count)" -ForegroundColor $global:colorMain -LogFile $LogFiles
				If ($G.RomsUnscraped -eq 0)
				{
					Write-Out -Text "* -ROMs Not Scraped: $($G.RomsUnscraped)" -ForegroundColor $global:colorMain -LogFile $LogFiles
				}
				Else 
				{
					Write-Out -Text "* -ROMs Not Scraped: ","$($G.RomsUnscraped)" -ForegroundColor $global:colorMain,$global:colorError -LogFile $LogFiles
				}
				If ($G.MissingXmlData -eq 0)
				{
					Write-Out -Text "* -Missing Data    : $($G.MissingXmlData)" -ForegroundColor $global:colorMain -LogFile $LogFiles
				}
				Else 
				{
					Write-Out -Text "* -Missing Data    : ","$($G.MissingXmlData)" -ForegroundColor $global:colorMain,$global:colorError -LogFile $LogFiles
				}
				If ($G.DuplicateRoms -eq 0)
				{
					Write-Out -Text "* -Duplicate ROMs  : $($G.DuplicateRoms)" -ForegroundColor $global:colorMain -LogFile $LogFiles
				}
				Else 
				{
					Write-Out -Text "* -Duplicate ROMs  : ","$($G.DuplicateRoms)" -ForegroundColor $global:colorMain,$global:colorError -LogFile $LogFiles
				}
			}
			Write-Out -ForegroundColor $global:colorMain -Text "* -Start Time      : $($G.GameStart)" -LogFile $LogFiles
			Write-Out -ForegroundColor $global:colorMain -Text "* -End Time        : $($G.GameEnd)" -LogFile $LogFiles
			Write-Out -ForegroundColor $global:colorMain -Text "* -Elapsed Time    : $([math]::Round(($G.GameEnd-$G.GameStart).totalseconds, 2)) seconds" -LogFile $LogFiles
			Write-Out -ForegroundColor $global:colorMain -Text "* " -LogFile $LogFiles
		}
	}
	$ScriptEnd = (Get-Date)
	Write-Out -Text "* **************************************************************" -ForegroundColor $global:colorMain -LogFile $LogFiles
	Write-Out -ForegroundColor $global:colorMain -Text "* Script Start Time      : $($ScriptStart)" -LogFile $LogFiles
	Write-Out -ForegroundColor $global:colorMain -Text "* Script End Time        : $($ScriptEnd)" -LogFile $LogFiles
	Write-Out -ForegroundColor $global:colorMain -Text "* Script Elapsed Time    : $([math]::Round(($ScriptEnd-$ScriptStart).totalseconds, 2)) seconds" -LogFile $LogFiles	


	
	
}


Function Check-GamesListXML
{
	Param
	(	
		[Parameter(Mandatory=$true)]
		[System.Collections.Specialized.OrderedDictionary]$RomHashTable,
		
		[Parameter(Mandatory=$true)]
		[Alias("GameList")]
		[string]$GameListRoot,

		[Parameter(Mandatory=$true)]
		[System.Collections.Specialized.OrderedDictionary]$ValidateData,		

		[Parameter(Mandatory=$true)]
		[Alias("Splitstr")] 
		[AllowEmptyString()]
		[string]$RomManualSplitstr,
		
		[Parameter(Mandatory=$true)]
		[Alias("Filters")] 
		[string]$RomFiltersDir = "",
		
		[Parameter(Mandatory=$true)]
		[bool]$FindDuplicates,
		
		[Parameter(Mandatory=$true)]
		[bool]$IgnoreMulticartDuplicates,
		
		[Parameter(Mandatory=$false)]
		[string[]]$MultiCartExceptions,
		
		[Parameter(Mandatory=$true)]
		[Alias("Log")]
		[string[]]$LogFiles
	)

	#Array to Track Results For Each Game System
	$gameArray = @()

	#Check XML Gamelists for Missing Scraped Metadata
	ForEach ($GameSystem in $RomHashTable.keys)
	{
		#Create Object to Store Info For Each Game System
		$gameObject = [PSCustomObject]@{
			GameSystem = $GameSystem
			GameList = "$($GameListRoot)$($GameSystem)\gamelist.xml"
			GameListExist = $false
			RomFilters = "$($RomFiltersDir)$($GameSystem).ps1"
			Games = @{}
			RomsUnscraped = 0
			MissingXmlData = 0
			DuplicateRoms = 0
			GameStart = (get-date)
			GameEnd = (get-date)
		}

		Write-Out -ForegroundColor $global:colorMain -Text "****************************************************************" -LogFile $LogFiles
		Write-Out -Text "PROCESSING: $($GameSystem)" -ForegroundColor $global:colorMain -LogFile $LogFiles
		Write-Out -ForegroundColor $global:colorMain -Text "****************************************************************" -LogFile $LogFiles
		Write-Out -ForegroundColor $global:colorSub1 -Text "Description           : $($RomHashTable[$GameSystem])" -LogFile $LogFile
		Write-Out -ForegroundColor $global:colorSub1 -Text "Game List XML         : $($gameObject.GameList)" -LogFile $LogFile
		Write-Out -ForegroundColor $global:colorSub1 -Text "ValidateData          :" -NoNewLine -LogFile $LogFile
		$i = 0
		$ValidateData.GetEnumerator() | ForEach-Object {
			If ($i -eq 0)
			{
				Write-Out -ForegroundColor $global:colorSub1 -Text " $($_.Key) = $($_.Value)" -LogFile $LogFile
			}
			Else
			{
				Write-Out -ForegroundColor $global:colorSub1 -Text "                      : $($_.Key) = $($_.Value)" -LogFile $LogFile
			}
			$i++
		}
		If ([string]::IsNullOrEmpty($RomManualSplitstr))
		{
			Write-Out -ForegroundColor $global:colorSub1 -Text "Manual Splitstr       : Not Set - Import from ROM Filters" -LogFile $LogFile
		}
		Else
		{
			Write-Out -ForegroundColor $global:colorSub1 -Text "Manual Splitstr       : $($RomManualSplitstr)" -LogFile $LogFile
		}
		Write-Out -ForegroundColor $global:colorSub1 -Text "ROM Filters           : $($gameObject.RomFilters)" -LogFile $LogFile
		Write-Out -ForegroundColor $global:colorSub1 -Text "Find Duplipcates      : $($IgnoreMulticartDuplicates)" -LogFile $LogFile
		Write-Out -ForegroundColor $global:colorSub1 -Text "Ignore Multicart Dup  : $($IgnoreMulticartDuplicates)" -LogFile $LogFile
		If ($MultiCartExceptions.Count -le 0)
		{
			Write-Out -ForegroundColor $global:colorSub1 -Text "Manual MultiCart Excp : Not Set - Import from ROM Filters" -LogFile $LogFile
		}
		Else
		{
			Write-Out -ForegroundColor $global:colorSub1 -Text "Manual MultiCart Excp : $($MultiCartExceptions -Join "`n`t`t`t")" -LogFile $LogFile
		}
		Write-Out -ForegroundColor $global:colorSub1 -Text "Log Files             : $($LogFiles)" -LogFile $LogFile
		Write-Out -ForegroundColor $global:colorSub1 -Text "Start Time            : $($GameStart)" -LogFile $LogFile

		#Game System Start
		Write-Out -Text "$($GameSystem.ToUpper()) (STEP 1/4): Confirm XML Exists" -ForegroundColor $global:colorMain -LogFile $LogFiles
		Write-Out -Text "================================================================" -ForegroundColor $global:colorMain -LogFile $LogFiles
		If (!(Test-Path -LiteralPath $gameObject.GameList -PathType Leaf))
		{
			Write-Out -Text "ERROR Skip - XML File Not Exist: $($gameObject.GameList)" -ForegroundColor $global:colorError -LogFile $LogFiles
			
			Write-Out -Text "$($GameSystem.ToUpper()) (STEP 2/4): Validate Game Data" -ForegroundColor $global:colorMain -LogFile $LogFiles
			Write-Out -Text "================================================================" -ForegroundColor $global:colorMain -LogFile $LogFiles			
			Write-Out -Text "ERROR Skip - XML File Not Exist: $($gameObject.GameList)" -ForegroundColor $global:colorError -LogFile $LogFiles
			
			Write-Out -Text "$($GameSystem.ToUpper()) (STEP 3/4): Check For Duplicates" -ForegroundColor $global:colorMain -LogFile $LogFiles
			Write-Out -Text "================================================================" -ForegroundColor $global:colorMain -LogFile $LogFiles			
			Write-Out -Text "ERROR Skip - XML File Not Exist: $($gameObject.GameList)" -ForegroundColor $global:colorError -LogFile $LogFiles
		}
		Else
		{
			#Read GameList.xml
			$gameObject.GameListExist = $true
			Write-Out -Text "Exists - Continue: $($gameObject.GameList)" -ForegroundColor $global:colorSub1 -LogFile $LogFiles
			[XML]$gameXml = Get-Content $gameObject.GameList
			
			#Loop Each Game in the XML File and Validate Properties Set to True
			Write-Out -Text "$($GameSystem.ToUpper()) (STEP 2/4): Validate Game Data" -ForegroundColor $global:colorMain -LogFile $LogFiles
			Write-Out -Text "================================================================" -ForegroundColor $global:colorMain -LogFile $LogFiles			
			ForEach($gameXmlData in $gameXml.gameList.game)
			{
				$RomScraped = $true
				$MissingXmlElements = @()
				ForEach ($Element in $ValidateData.keys)
				{
					If ($ValidateData[$Element] -eq $true)
					{
						If ($gameXmlData.$Element -eq "" -OR $gameXmlData.$Element -eq $null)
						{
							$gameObject.MissingXmlData++
							$RomScraped = $false
							$MissingXmlElements += $Element
						}
					}
				}
				If ($MissingXmlElements.Count -gt 0)
				{
					Write-Out -Text "$($gameXmlData.path)" -ForegroundColor $global:colorSub2 -LogFile $LogFiles
					Write-Out -Text "-------------------------------------" -ForegroundColor $global:colorSub2 -LogFile $LogFiles
					ForEach ($MissingXmlElement in $MissingXmlElements)
					{
						Write-Out -Text "$($MissingXmlElement): ","MISSING" -ForegroundColor $global:colorSub2,$global:colorError -LogFile $LogFiles
					}
					Write-Out -LogFile $LogFiles
				}
				If ($RomScraped -eq $false)
				{
					$gameObject.RomsUnscraped++
				}

				#Add Game Name and Path to HashTable To Check For Duplicate Games
				If ($gameObject.Games.ContainsKey($gameXmlData.name))
				{
					$gameObject.Games[$gameXmlData.name] += $gameXmlData.path
				}
				Else
				{
					$gameObject.Games[$gameXmlData.name] = @($gameXmlData.path)
				}
			}

			Write-Out -Text "----------------------------------------" -ForegroundColor $global:colorMain -LogFile $LogFiles
			If ($gameObject.MissingXmlData -eq 0)
			{
				Write-Out -Text "Validation - Successful with $($gameObject.MissingXmlData) Errors" -ForegroundColor $global:colorSub1 -LogFile $LogFiles
			}
			Else
			{
				Write-Out -Text "Validation - ","Failed with Unscraped ROMs: $($gameObject.RomsUnscraped) and Missing Metadata: $($gameObject.MissingXmlData)" -ForegroundColor $global:colorSub1,$global:colorError -LogFile $LogFiles
			}

			#Check For Duplicate Games
			Write-Out -Text "$($GameSystem.ToUpper()) (STEP 3/4): Check For Duplicates" -ForegroundColor $global:colorMain -LogFile $LogFiles
			Write-Out -Text "================================================================" -ForegroundColor $global:colorMain -LogFile $LogFiles
			If (!$FindDuplicates)
			{
				Write-Out -Text "Skip - FindDuplicates Variable Set to false" -ForegroundColor $global:colorWarn -LogFile $LogFiles
			}
			Else
			{
				#Import Variables from ROM Filters by Dot Sourcing ($romSplitstr, $romsMultiCart)
				Write-Out -ForegroundColor $global:colorSub1 -Text "Import Variables from $($gameObject.RomFilters)" -LogFile $LogFile
				. "$($gameObject.RomFilters)"
				
				#Set $romSplitstr by Import from ROM Filters or Manually by Global Variable
				If ([string]::IsNullOrEmpty($RomManualSplitstr))
				{
					Write-Out -Text "Set `$romSplitstr (Import): $($romSplitstr)" -ForegroundColor $global:colorSub1 -LogFile $LogFiles
				}
				Else
				{
					$romSplitstr = $RomManualSplitstr
					Write-Out -Text "Set `$romSplitstr (Manual): $($romSplitstr)" -ForegroundColor $global:colorSub1 -LogFile $LogFiles
				}
				
				#Set $romsMultiCart by Import from ROM Filters or Manually by Global Variable
				If ($MultiCartExceptions.Count -le 0)
				{
					Write-Out -Text "Set `$romsMultiCart (Import): $($romsMultiCart -Join "`n`t`t`t     ")" -ForegroundColor $global:colorSub1 -LogFile $LogFiles
				}
				Else
				{
					$romsMultiCart = $MultiCartExceptions
					Write-Out -Text "Set `$romsMultiCart (Manual): $($romsMultiCart -Join "`n`t`t`t     ")" -ForegroundColor $global:colorSub1 -LogFile $LogFiles
				}

				#Confirm romSplitstr is Set to Determine Unique ROM Names
				If ([string]::IsNullOrEmpty($romSplitstr))
				{
					#No Split string to Determine Unique ROM Name
					Write-Out -ForegroundColor $global:colorWarn -Text "Skip - No Split String Defined in `$romSplitstr to Determine Unique ROM Name" -LogFile $LogFile
				}
				Else
				{
					#Get List of Unique ROM Names
					[array]$colUniqueRoms = @()
					$colUniqueRoms = $gameObject.Games.GetEnumerator() | ForEach { (($_.key) -Split $romSplitstr)[0] } | Sort-Object -Unique
					If ($romSortAscending)
					{
						$colUniqueRoms = Sort-Naturally -Array $colUniqueRoms
					}
					Else
					{
						$colUniqueRoms = Sort-Naturally -Array $colUniqueRoms -Descending
					}
					Write-Out -Text "Unique Names: $($colUniqueRoms.Count) " -ForegroundColor $global:colorSub1 -LogFile $LogFiles
					Write-Out -Text "Total ROMs: $($gameObject.Games.Count) " -ForegroundColor $global:colorSub1 -LogFile $LogFiles
					If ($gameObject.Games.Count -gt $colUniqueRoms.Count)
					{
						Write-Out -Text "Potential Duplicates: $($gameObject.Games.Count - $colUniqueRoms.Count)" -ForegroundColor $global:colorWarn -LogFile $LogFiles
					}
					Else 
					{
						Write-Out -Text "Potential Duplicates: $($gameObject.Games.Count - $colUniqueRoms.Count)" -ForegroundColor $global:colorSub1 -LogFile $LogFiles
					}
					
					#Find Duplicates
					ForEach ($uniqueRom in $colUniqueRoms)
					{
						#Get HashTable Key for Each Duplicate
						$Duplicates = $gameObject.Games.Keys -match ("^"+[regex]::escape($uniqueRom)+$romSplitstr)
						If ($IgnoreMulticartDuplicates -AND $Duplicates.Count -gt 0)
						{
							If ($romsMultiCart.Count -gt 0)
							{
								ForEach ($Multicart in $romsMultiCart)
								{
									$Duplicates = $Duplicates -cnotmatch $Multicart
								}
							}							
						}
							
						If ($Duplicates.Count -gt 1)
						{
							$DupRomsCount = (($Duplicates | ForEach-Object {$gameObject.Games[$_]}).Count -1)
							$gameObject.DuplicateRoms += $DupRomsCount
							Write-Out -Text "Duplicate($($DupRomsCount)): $($uniqueRom)" -ForegroundColor $global:colorSub2 -LogFile $LogFiles
							Write-Out -Text "----------------------------------------" -ForegroundColor $global:colorSub2 -LogFile $LogFiles	
							ForEach ($Dup in $Duplicates)
							{
								$gameObject.Games[$Dup] | ForEach-Object {Write-Out -Text "ROM: ","$($_)" -ForegroundColor $global:colorSub2,$global:colorError -LogFile $LogFiles}
							}
							Write-Out -LogFile $LogFiles
						}
					}
					Write-Out -Text "----------------------------------------" -ForegroundColor $global:colorMain -LogFile $LogFiles					
					If ($gameObject.DuplicateRoms -eq 0)
					{
						Write-Out -Text "Duplicates: None Found" -ForegroundColor $global:colorSub1 -LogFile $LogFiles
					}
					Else 
					{
						Write-Out -Text "Duplicates: ","$($gameObject.DuplicateRoms) Found" -ForegroundColor $global:colorSub1,$global:colorError -LogFile $LogFiles
					}
				}
			}
		}
		
		#Game System Result
		Write-Out -Text "$($GameSystem.ToUpper()) (STEP 4/4): Processing Results" -ForegroundColor $global:colorMain -LogFile $LogFiles
		Write-Out -Text "================================================================" -ForegroundColor $global:colorMain -LogFile $LogFiles
		Write-Out -Text "$($gameObject.GameSystem):" -ForegroundColor $global:colorMain -LogFile $LogFiles
		If ($gameObject.GameListExist -eq $false)
		{
			Write-Out -Text "ERROR - XML File Not Exist: ($($gameObject.GameList))" -ForegroundColor $global:colorError -LogFile $LogFiles
			Write-Out -Text "-Total Games     : ","N/A" -ForegroundColor $global:colorSub1,$global:colorError -LogFile $LogFiles
			Write-Out -Text "-ROMs Not Scraped: ","N/A" -ForegroundColor $global:colorSub1,$global:colorError -LogFile $LogFiles
			Write-Out -Text "-Missing Data    : ","N/A" -ForegroundColor $global:colorSub1,$global:colorError -LogFile $LogFiles
			Write-Out -Text "-Duplicate ROMs  : ","N/A" -ForegroundColor $global:colorSub1,$global:colorError -LogFile $LogFiles
		}
		Else 
		{
			Write-Out -Text "-Total Games     : $($gameObject.Games.Count)" -ForegroundColor $global:colorSub1 -LogFile $LogFiles
			If ($gameObject.RomsUnscraped -eq 0)
			{
				Write-Out -Text "-ROMs Not Scraped: $($gameObject.RomsUnscraped)" -ForegroundColor $global:colorSub1 -LogFile $LogFiles
			}
			Else 
			{
				Write-Out -Text "-ROMs Not Scraped: ","$($gameObject.RomsUnscraped)" -ForegroundColor $global:colorSub1,$global:colorError -LogFile $LogFiles
			}
			If ($gameObject.MissingXmlData -eq 0)
			{
				Write-Out -Text "-Missing Data    : $($gameObject.MissingXmlData)" -ForegroundColor $global:colorSub1 -LogFile $LogFiles
			}
			Else 
			{
				Write-Out -Text "-Missing Data    : ","$($gameObject.MissingXmlData)" -ForegroundColor $global:colorSub1,$global:colorError -LogFile $LogFiles
			}
			If ($gameObject.DuplicateRoms -eq 0)
			{
				Write-Out -Text "-Duplicate ROMs  : $($gameObject.DuplicateRoms)" -ForegroundColor $global:colorSub1 -LogFile $LogFiles
			}
			Else 
			{
				Write-Out -Text "-Duplicate ROMs  : ","$($gameObject.DuplicateRoms)" -ForegroundColor $global:colorSub1,$global:colorError -LogFile $LogFiles
			}
		}
		Write-Out -ForegroundColor $global:colorSub1 -Text "-Start Time      : $($gameObject.GameStart)" -LogFile $LogFiles
		$gameObject.GameEnd = (get-date)
		Write-Out -ForegroundColor $global:colorSub1 -Text "-End Time        : $($gameObject.GameEnd)" -LogFile $LogFiles
		Write-Out -ForegroundColor $global:colorSub1 -Text "-Elapsed Time    : $([math]::Round(($gameObject.GameEnd-$gameObject.GameStart).totalseconds, 2)) seconds" -PostLine 1 -LogFile $LogFiles	
		
		#Add Game System to Array to Track Results
		$gameArray += $gameObject
	}
	
	#Return All Game System Results
	Return $gameArray
}



Function Sort-Naturally
{
	#https://github.com/LarrysGIT/Powershell-Natural-sort/blob/master/NaturalSort.ps1
    PARAM(
        [Parameter(ValueFromPipeline=$true)]
        [System.Collections.ArrayList]$Array,
        [String]$Property,
        [switch]$Descending
    )

    Add-Type -TypeDefinition @'
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace NaturalSort {
    public static class NaturalSort
    {
        [DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
        public static extern int StrCmpLogicalW(string psz1, string psz2);
        public static System.Collections.ArrayList Sort(System.Collections.ArrayList foo)
        {
            foo.Sort(new NaturalStringComparer());
            return foo;
        }
    }
    public class NaturalStringComparer : IComparer
    {
        public int Compare(object x, object y)
        {
            return NaturalSort.StrCmpLogicalW(x.ToString(), y.ToString());
        }
    }
}
'@
    If ($Array)
	{
		If($Property)
		{
			$ArrayTmp = @{}
			foreach($obj in $Array)
			{
				$ArrayTmp.Add(("{0}_{1}" -f $obj.$Property, $obj.GetHashCode()), $obj)
			}
			$Keys = New-Object System.Collections.ArrayList
			$Keys.AddRange(@($ArrayTmp.Keys))
			$Keys.Sort((New-Object NaturalSort.NaturalStringComparer))
			$Array.Clear()
			ForEach($k in $Keys)
			{
				$Array.Add($ArrayTmp[$k]) | Out-Null
			}
		}
		Else
		{
			$Array.Sort((New-Object NaturalSort.NaturalStringComparer))
		}
		If($Descending)
		{
			$Array.Reverse()
		}
	}
    Return $Array
}



Function Validate-Container
{
    Param (
        [Parameter(Mandatory=$true)]
        [string]$Name,
		
		[Parameter(Mandatory=$true)]
        [ref]$Path,
		
		[Parameter(Mandatory=$false)]
		[switch]$IsValid,
		
		[Parameter(Mandatory=$false)]
		[switch]$EndsWithBackslash,
		
		[Parameter(Mandatory=$true)]
		[Alias("Log")]
		[string[]]$LogFiles
    )
	
	Write-Out -ForegroundColor $global:colorSub1 -Text "$($Name) " -NoNewLine -LogFile $LogFiles
	
	If (([URI]$Path.Value).IsUnc)
	{
		#Path is UNC
		If ($IsValid)
		{
			#Confirm It is Valid (Must have folder in path not just server name)
			If (Test-Path -LiteralPath $Path.Value -IsValid)
			{
				Write-Out -ForegroundColor $global:colorSub1 -Text "Path (UNC) Valid: '$($Path.Value)'" -LogFile $LogFiles
			}
			Else
			{
				Write-Out -ForegroundColor $global:colorError -Text "Path (UNC) NOT Valid: '$($Path.Value)'" -LogFile $LogFiles
				Return $false
			}
		}
		Else
		{
			#Confirm It Exists (Must have folder in path not just server name)
			If (Test-Path -LiteralPath $Path.Value)
			{
				Write-Out -ForegroundColor $global:colorSub1 -Text "Path (UNC) Exist: '$($Path.Value)'" -LogFile $LogFiles
			}
			Else
			{
				Write-Out -ForegroundColor $global:colorError -Text "Path (UNC) NOT Exist: '$($Path.Value)'" -LogFile $LogFiles
				Return $false
			}
		}
	}
	Else
	{
		#Path is Local
		If ($IsValid)
		{
			#Confirm It is Valid
			If (Test-Path -LiteralPath $Path.Value -IsValid)
			{
				Write-Out -ForegroundColor $global:colorSub1 -Text "Path (Local) Valid: '$($Path.Value)'" -LogFile $LogFiles
			}
			Else
			{
				Write-Out -ForegroundColor $global:colorError -Text "Path (Local) NOT Valid: '$($Path.Value)'" -LogFile $LogFiles
				Return $false
			}
		}
		Else
		{
			#Confirm It is a Container
			If (Test-Path -LiteralPath $Path.Value -PathType Container)
			{
				Write-Out -ForegroundColor $global:colorSub1 -Text "Path (Local) Exist: '$($Path.Value)'" -LogFile $LogFiles
			}
			Else
			{
				Write-Out -ForegroundColor $global:colorError -Text "Path (Local) NOT Exist: '$($Path.Value)'" -LogFile $LogFiles
				Return $false
			}
		}
	}
    
	If ($EndsWithBackslash)
	{
		If (!$Path.Value.EndsWith('\'))
		{
			$Path.Value = $Path.Value + "\"
			Write-Out -ForegroundColor $global:colorWarn -Text "Path Not End with '\', append it: $($Path.Value)" -LogFile $LogFiles
		}
	}
	
	Return $true
}



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. Array of Absolute or relative path of the log file(s). You can still provide a single log file or multiple separate by commas.
	.PARAMETER LogOnly
	Optional. Write to LogFile only, do Not output to console.
	.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: https://sigkillit.com/
	Created: 5/23/2023
	Version 1.5
	- Removed Unnecessary loop in 1.4 for log files since Test-Path, New-Item, Set-Content, and Add-Content all support -Path as string array
	Version 1.4
	- Changed LogFile from a String to String Array so you can log the same line to multiple files or provide a single value so it' backwards compatible.
	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"
	.EXAMPLE
	Write-Out -Text "You can write this line to two log files now" -LogFile "script.log","second.txt"
	#>
	[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.Count -eq 0)
		{
			#No LogFile Specified - Skip
		}
		ElseIf ($LogFile.Count -gt 0)
		{
			#LogFile Specified - Loop Array
			If(!(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

2 pings

  1. […] ← Previous Next → […]

  2. […] 3_CheckXML.ps1 to check for missing scraped data in RetroPie […]

Comments have been disabled.