.PARAMETER EnableException
By default, when something goes wrong we try to catch it, interpret it and give you a friendly warning message.
This avoids overwhelming you with "sea of red" exceptions, but is inconvenient because it basically disables advanced scripting.
Using this switch turns this "nice by default" feature off and enables you to catch exceptions with your own try/catch.

Queries CMS server to return all SQL instances in the Production folder and then list out all agent jobs that have either been disabled or have no schedule.

#>[CmdletBinding()]param([parameter(Mandatory,ValueFromPipeline)][DbaInstanceParameter[]]$SqlInstance,[PSCredential]$SqlCredential,[Alias("Name")][string[]]$JobName,[string[]]$ExcludeJobName,[string[]]$StepName,[int]$LastUsed,[Alias("Disabled")][switch]$IsDisabled,[Alias("Failed")][switch]$IsFailed,[Alias("NoSchedule")][switch]$IsNotScheduled,[Alias("NoEmailNotification")][switch]$IsNoEmailNotification,[string[]]$Category,[string]$Owner,[datetime]$Since,[switch]$EnableException)begin{if($IsFailed,[boolean]$JobName,[boolean]$StepName,[boolean]$LastUsed.ToString(),$IsDisabled,$IsNotScheduled,$IsNoEmailNotification,[boolean]$Category,[boolean]$Owner,[boolean]$ExcludeJobName-notcontains$true){Stop-Function-Message"At least one search term must be specified"}}process{if(Test-FunctionInterrupt){return}

if($JobName){Write-Message-LevelVerbose-Message"Retrieving jobs by their name."$output+=Get-JobList-SqlInstance$server-JobFilter$JobName}

if($StepName){Write-Message-LevelVerbose-Message"Retrieving jobs by their step names."$output+=Get-JobList-SqlInstance$server-StepFilter$StepName}

if($LastUsed){$DaysBack=$LastUsed*-1$SinceDate=(Get-date).AddDays($DaysBack)Write-Message-LevelVerbose-Message"Finding job/s not ran in last $LastUsed days"$output+=$jobs|Where-Object{$_.LastRunDate-le$SinceDate}}

if($IsDisabled){Write-Message-LevelVerbose-Message"Finding job/s that are disabled"$output+=$jobs|Where-ObjectIsEnabled-eq$false}

if($IsNotScheduled){Write-Message-LevelVerbose-Message"Finding job/s that have no schedule defined"$output+=$jobs|Where-ObjectHasSchedule-eq$false}if($IsNoEmailNotification){Write-Message-LevelVerbose-Message"Finding job/s that have no email operator defined"$output+=$jobs|Where-Object{[string]::IsNullOrEmpty($_.OperatorToEmail)-eq$true}}

if($Category){Write-Message-LevelVerbose-Message"Finding job/s that have the specified category defined"$output+=$jobs|Where-Object{$Category-contains$_.Category}}

if($Owner){Write-Message-LevelVerbose-Message"Finding job/s with owner critera"if($Owner-match"-"){$OwnerMatch=$Owner-replace"-",""Write-Message-LevelVerbose-Message"Checking for jobs that NOT owned by: $OwnerMatch"$output+=$server.JobServer.jobs|Where-Object{$OwnerMatch-notcontains$_.OwnerLoginName}}else{Write-Message-LevelVerbose-Message"Checking for jobs that are owned by: $owner"$output+=$server.JobServer.jobs|Where-Object{$Owner-contains$_.OwnerLoginName}}}

if($Exclude){Write-Message-LevelVerbose-Message"Excluding job/s based on Exclude"$output=$output|Where-Object{$Exclude-notcontains$_.Name}}

if($Since){#$Since = $Since.ToString("yyyy-MM-dd HH:mm:ss")Write-Message-LevelVerbose-Message"Getting only jobs whose LastRunDate is greater than or equal to $since"$output=$output|Where-Object{$_.LastRunDate-ge$since}}

Select-DefaultView-InputObject$job-PropertyComputerName,InstanceName,SqlInstance,Name,Category,OwnerLoginName,CurrentRunStatus,CurrentRunRetryAttempt,'IsEnabled as Enabled',LastRunDate,LastRunOutcome,DateCreated,HasSchedule,OperatorToEmail,'DateCreated as CreateDate'}}}}