Skip to content

PowerShell

Microsoft PowerShell Scripts are the newest method of scripting in Microsoft Windows.

Here are a few of the scripts I have written that may be of use to the general public.

DiskSize

This script calculates the drive space for the drive where this script is running from.

<#    
.SYNOPSIS   
Script that calculates the drive space for the drive where this script is running from.

.DESCRIPTION 
This script first calculates the path where this script is running from.
It then get drive information for all drives and mount points whose names are contained in that path.
The results are sorted by the lengths of the drive names in descending order and the top one is returned.
This drive is the drive or mount point that is closest to the script's path.

.NOTES   
Name: DiskSize.ps1
Author: Mike Shook

Version: 1.0.0.1
Version Date: 03/20/2021

#>

#Clear-Host

########################################################
# From https://stackoverflow.com/questions/57530347/how-to-convert-value-to-kb-mb-or-gb-depending-on-digit-placeholders/57535324#57535324

$Shlwapi = Add-Type -MemberDefinition '
    [DllImport("Shlwapi.dll", CharSet=CharSet.Auto)]public static extern int StrFormatByteSize(long fileSize, System.Text.StringBuilder pwszBuff, int cchBuff);
' -Name "ShlwapiFunctions" -namespace ShlwapiFunctions -PassThru

Function Format-ByteSize([Long]$Size) {
    $Bytes = New-Object Text.StringBuilder 20
    $Return = $Shlwapi::StrFormatByteSize($Size, $Bytes, $Bytes.Capacity)
    If ($Return) {$Bytes.ToString()}
}
########################################################

# get the folder the script is currently running from
$fullPath = $MyInvocation.MyCommand.Path
$parentPath = ( Split-Path $fullPath -Parent ) + "\"

# get list of all drive and mountpoint names that are in the script's path

########################################################
# from http://www.bradleyschacht.com/checkmountpointsfreespacewithpowershel/
# gwmi win32_volume|where-object {$_.filesystem -match “ntfs”}|ft name,capacity,freespace
########################################################

$drives = gwmi win32_volume `
    | Where-Object { $parentPath -like "*" + $_.name + "*" } `
    | Select-Object name, @{Name = "name_length"; Expression = { $_.name.Length } }, @{Name = "capacity"; Expression = { Format-ByteSize $_.capacity } }, @{ Name = "freespace"; Expression = { Format-ByteSize $_.freespace } } 

# Find longest name as that will be the nearest drive to the script's path

$drive = $drives | Sort-Object -Property @{Expression = "name_length"; Descending = $True} | Select-Object -First 1

# If there were no drives, assume a UNC path or mapped drive

if( $drive.name -ne $null ){

    # output nearest drive information
    $drive | Format-Table -Property name, capacity, freespace

} else {

    # output message
    Write-Output "No information found. Is this script on a Mapped Drive or UNC Path?"

}
# set non-ISE powershell terminal to wait for keypress

If (!$psISE) {
    Read-Host "Press ENTER to Exit..."
}

EspnFantasyFootballLineup

This script calculates a ESPN Fantasy Football team's starting lineup for current week.

<#    
.SYNOPSIS   
Script that calculates a ESPN Fantasy Football team's starting lineup for current week.

.DESCRIPTION 
This script gets the roster data for an ESPN Fantasy Football team for the current week.
It then calculates for each player a value that represents that players starting value.
This value is meaningless EXCEPT for comparison with other player's values that play the same position.
It is then used to create the team's starting lineup for the week.
Then the values used, grouped by player position, are displayed.
Last, the final lineup for the week is displayed.
The calculation formula is found in the expression set for the 'Comparison' node when the Base data is calculated.

.NOTES   
Name: EspnFantasyFootballLineup.ps1
Author: Mike Shook

Version: 1.2.0.
Version Date: 12/13/2020
Version Notes: Added ability to always have locked players marked with where they were when they played

Version: 1.1.0.
Version Date: 10/21/2020
Version Notes: Added output of the current and new projected total points

.VARIABLE $leagueId
The ID of the league the team is a member of.
It can be found in the url of your team page:
https://fantasy.espn.com/football/team?leagueId=76968740&teamId=13&seasonId=2020
                                                ^^^^^^^^

.VARIABLE $teamId
The ID of the team in the league.
It can be found in the url of your team page:
https://fantasy.espn.com/football/team?leagueId=76968740&teamId=13&seasonId=2020
                                                                ^^

.VARIABLE $deleteFiles
Whether or not you want the temp files used during the run of this script to be deleted at the end.
Allowed vales are $True or $False

.MODULE WriteAscii
The WriteAscii module is required for pretty team names in the output.
To install it run from elevated powershell: "Install-Module -Name WriteAscii"

#>

### User Variables #######################################
$leagueId = '76968740'
$teamId = '13'
##########################################################

### No user changes beyond this point #####################

# Clear the host display and set height to match the Calculated Lineup Report

Clear-Host

If ($host.Name -eq 'ConsoleHost') {
    If (Get-Module -ListAvailable -Name WriteAscii) {
        $host.UI.RawUI.WindowSize = New-Object System.Management.Automation.Host.size(120, 47)
    }
    else {
        $host.UI.RawUI.WindowSize = New-Object System.Management.Automation.Host.size(120, 34)
    }
}

# Get basic data from ESPN for the current week

Write-Host "Getting data for Team $teamId in League $leagueId..." -ForegroundColor Yellow

$year = Get-Date -Format "yyyy"

$uriBasic = 'https://fantasy.espn.com/apis/v3/games/ffl/seasons/' + $year + '/segments/0/leagues/' + $leagueId

$GetSession = Invoke-WebRequest -Uri $uriBasic -Method GET -timeoutSec 360 -ErrorAction Stop

$basic = $GetSession.Content | ConvertFrom-Json

$week = $basic.scoringPeriodId

# Set paths to all temp files and delete any old ones

$path = $env:TEMP 

$fileJson = $path + '\ESPN_FFL_Lineup_' + $leagueId + '_' + $teamId + '_' + $week + '.json'
$fileBaseCsv = $path + '\ESPN_FFL_Lineup_' + $leagueId + '_' + $teamId + '_' + $week + '_base.csv'
$fileComparisonCsv = $path + '\ESPN_FFL_Lineup_' + $leagueId + '_' + $teamId + '_' + $week + '_comparison.csv'
$fileSortedCsv = $path + '\ESPN_FFL_Lineup_' + $leagueId + '_' + $teamId + '_' + $week + '_sorted.csv'
$fileStartCsv = $path + '\ESPN_FFL_Lineup_' + $leagueId + '_' + $teamId + '_' + $week + '_start.csv'
$fileChangeCsv = $path + '\ESPN_FFL_Lineup_' + $leagueId + '_' + $teamId + '_' + $week + '_change.csv'
$fileCollection = $path + '\ESPN_FFL_Lineup_' + $leagueId + '_' + $teamId + '_' + $week + '*.*'

$currentProjected = 0
$newProjected = 0

Remove-Item -Path $fileCollection -ErrorAction SilentlyContinue

# Get the stats information from ESPN

$uriStats = 'https://fantasy.espn.com/apis/v3/games/ffl/seasons/' + $year + '/segments/0/leagues/' + $leagueId + '?rosterForTeamId=' + $teamId + '&view=mRoster&view=mTeam&scoringPeriodId=' + $week

$GetSession = Invoke-WebRequest -Uri $uriStats -Method GET -timeoutSec 360 -ErrorAction Stop

$GetSession.Content | Out-File $fileJson

$json = $GetSession.Content | ConvertFrom-Json

# Get the team information

$team = $json.teams[$teamId - 1]

$teamName = $team.location + ' ' + $team.nickname

# Get the base data, calculate the comparison and write it out to a temp file

ForEach ($entry in $team.roster.entries) {  
    $entry | Select-Object @{ Name = 'Name'; Expression = { $entry.playerPoolEntry.player.fullName } }, `
        @{ Name = 'Slot'; Expression = { $entry.lineupSlotId } }, `
        @{ Name = 'Locked'; Expression = { $entry.playerPoolEntry.lineupLocked } }, `
        @{ Name = 'Position'; Expression = {
                Switch ([int]$entry.playerPoolEntry.player.defaultPositionId) {
                    { ($_ -eq 1) } { 'QB'; Break }
                    { ($_ -eq 2) } { 'RB'; Break }
                    { ($_ -eq 3) } { 'WR'; Break }
                    { ($_ -eq 4) } { 'TE'; Break }
                    { ($_ -eq 5) } { 'K'; Break }
                    { ($_ -eq 16) } { 'D/ST'; Break } 
                    Default { '??' }
                }
            }
        }, `
        @{ Name = 'defaultPositionId'; Expression = { [int]$entry.playerPoolEntry.player.defaultPositionId } }, `
        @{ Name = 'injured'; Expression = { $entry.playerPoolEntry.player.injured } }, `
        @{ Name = 'Status'; Expression = { $entry.playerPoolEntry.player.injuryStatus } }, `
        @{ Name = 'Started'; Expression = { [single]$entry.playerPoolEntry.player.ownership.percentStarted } }, `
        @{ Name = 'Ranking'; Expression = { [int]$entry.playerPoolEntry.ratings.'0'.positionalRanking } }, `
        @{ Name = 'Points'; Expression = { 
                ForEach ($stat in $entry.playerPoolEntry.player.stats) { 
                    If ( ( $stat.seasonId -eq '2020' ) -and ( $stat.scoringPeriodId -eq $week ) -and ( $stat.statSourceId -eq '1' ) ) { 
                        $stat.appliedTotal ` 
                    }
                }
            }
        }`
        | Export-Csv -Path $fileBaseCsv -NoTypeInformation -Append -Force
} 

# Load the base data, calculate the comparison, and write it out to a temp file

$comparisonTable = Import-Csv -Path $fileBaseCsv

ForEach ($player in $comparisonTable) {
    If ( [int]$player.slot -ne 20 ) { 
        $currentProjected = [single]$currentProjected + [single]$player.Points
    }
    $player | Select-Object Name, Slot, Locked, Position, defaultPositionId, injured, Status, Started, Ranking, Points, `
        @{ Name = 'Projected'; Expression = { [single]$currentProjected } }, ` 
        @{ Name = 'Comparison'; Expression = { If ( $player.Locked -eq $True -AND $player.Slot -ne '20' ) { [single]'100' + [single]$player.Points } ElseIf ( $player.Locked -eq $True -AND $player.Slot -eq '20' ) { [single]'-100' + [single]$player.Points } ElseIf ( [single]$player.Points -ne '0' -AND $player.injured -eq $False ) { [single]$player.Points + ([single]$player.Started / 6) - ( [int]$player.Ranking / 8) } Else { [single]'-100' } } }`
    | Export-Csv -Path $fileComparisonCsv -NoTypeInformation -Append -Force
}

# Load the comparison data, sort it by the positionId and Comparison, and write it out to a temp file

$sortedTable = Import-Csv -Path $fileComparisonCsv

$sortedTable | Sort-Object -Property @{Expression = { [int]$_.defaultPositionId }; Descending = $False }, `
@{Expression = { [single]$_.Comparison }; Descending = $True }`
| Export-Csv -Path $fileSortedCsv -NoTypeInformation -Force

# Load the sorted data, determine the start or bench status for each player, and write it out to a temp file

$startTable = Import-Csv -Path $fileSortedCsv

ForEach ($player in $startTable) {
    If ($player.defaultPositionId -ne $previousPositionId) { $rowCount = 1 } else { $rowCount = $rowCount + 1 }
    $previousPositionId = $player.defaultPositionId

    $player | Select-Object *, `
    @{ Name = 'rowCount'; Expression = { $rowCount } }, `
    @{ Name = 'Start ?'; Expression = {
            if ($_.defaultPositionId -eq 1 -and $rowCount -le 1) { 'START' } 
            elseif ($_.defaultPositionId -eq 2 -and $rowCount -le 2) { 'START' } 
            elseif ($_.defaultPositionId -eq 3 -and $rowCount -le 2) { 'START' }
            elseif ($_.defaultPositionId -eq 4 -and $rowCount -le 1) { 'START' }
            elseif ($_.defaultPositionId -eq 5 -and $rowCount -le 1) { 'START' }
            elseif ($_.defaultPositionId -eq 16 -and $rowCount -le 1) { 'START' }
            else { 'BENCH' }
        }
    }`
    | Export-Csv -Path $fileStartCsv -NoTypeInformation -Append -Force

}

# Load the start data, determine if a player is currently rostered incorrectly, and write it out to a temp file

$changeTable = Import-Csv -Path $fileStartCsv

ForEach ($player in $changeTable) {
    If ( $player.'Start ?' -eq 'START' ) { 
        $newProjected = [single]$newProjected + [single]$player.Points
    }
    $player | Select-Object *, `
        @{ Name = 'New'; Expression = { [single]$newProjected } }, `
        @{ Name = 'Change'; Expression = { If ($_.'Start ?' -eq 'START' -and $_.Slot -eq '20') { 'CHANGE' } 
            ElseIf ($_.'Start ?' -eq 'BENCH' -and $_.Slot -ne '20') { 'CHANGE' }
        } 
    }`
    | Export-Csv -Path $fileChangeCsv -NoTypeInformation -Append -Force

}

# Load the change data, set some variables used in the reports and clear the host display

$finalTable = Import-Csv -Path $fileChangeCsv

$width = $Host.UI.RawUI.BufferSize.Width
$lineThin = '-' * ( $width - 1 )
$lineThick = '=' * ( $width - 1 )

#Clear-Host

# Output the Calculated Comparison report

Write-Host $lineThin -ForegroundColor Red
If (Get-Module -ListAvailable -Name WriteAscii) {
    Write-Ascii -InputObject $team.location -ForegroundColor Cyan
    Write-Ascii -InputObject $team.nickname -ForegroundColor Cyan
    Write-Output ' '
    Write-Host "$year Week $week Calculated Comparison By Position:" -ForegroundColor Cyan
} 
Else {
    Write-Host "$teamName $year Week $week Calculated Comparison By Position:" -ForegroundColor Cyan
}

Write-Host 'Points + (Started / 6) - ( Ranking / 8)' -ForegroundColor Cyan

Write-Output $finalTable | Sort-Object -Property @{ Expression = { [int]$_.defaultPositionId }; Descending = $False }, `
@{ Expression = { [single]$_.Comparison }; Descending = $True }`
| Format-Table -Property Name, `
    @{Name = 'Injury Status'; Expression = { $_.Status } }, `
    @{Name = 'Projected'; Expression = { [math]::Round($_.Points, 2) } }, `
    @{Name = '% Started'; Expression = { [math]::Round($_.Started, 2) } }, `
    @{Name = 'Position Rank'; Expression = { [math]::Round($_.Ranking) } }, `
    @{Name = 'Comparison'; Expression = { [math]::Round($_.Comparison, 2) } }, `
    'Start ?', `
    Change `
    -GroupBy Position `
    -Wrap

# Output separator lines

Write-Output ' '
Write-Host $lineThick -ForegroundColor Red
Write-Output ' '
Write-Output ' '
Write-Output ' '
Write-Output ' '

# Output the Calculated Lineup report

If (Get-Module -ListAvailable -Name WriteAscii) {
    Write-Ascii -InputObject $team.location -ForegroundColor Green
    Write-Ascii -InputObject $team.nickname -ForegroundColor Green
    Write-Output ' '
    Write-Host "$year Week $week Calculated Lineup:" -ForegroundColor Green
} 
Else {
    Write-Host "$teamName $year Week $week Calculated Lineup:" -ForegroundColor Green
}

Write-Output $finalTable | Sort-Object -Property @{ Expression = { $_.'Start ?' }; Descending = $True }, `
@{ Expression = { [single]$_.defaultPositionId }; Descending = $False }`
| Format-Table -Property Position, `
    Name, `
    @{Name = 'Injury Status'; Expression = { $_.Status } }, `
    Locked, `
    Change ` `
    -GroupBy 'Start ?' `
    -Wrap

$currentProjected = [math]::Round($currentProjected, 2)
Write-Output "Current Projected Total: $currentProjected"
$newProjected = [math]::Round($newProjected, 2)
Write-Output "New Projected Total:     $newProjected"

Write-Host $lineThin -ForegroundColor Red

# set non-ISE powershell terminal to wait for keypress

If (!$psISE) {
    Read-Host "Press ENTER to Exit..."
}

FolderListBuild

This script uses Get-ChildItem and Measure-Object to query a folder and retreive all of its sub-folders and the counts of files and folders in each.

<#    
.SYNOPSIS   
Script that returns a list of sub-folders of an input folder

.DESCRIPTION 
This script uses Get-ChildItem and Measure-Object to query a folder and retreive all of its sub-folders and the counts of files and folders in each.

.PARAMETER QueryPath
The full path to the folder that will have its sub-folders listed

.PARAMETER OutputPath
The full path to the folder that will have the folder list

.NOTES   
Name: FolderListBuild.ps1
Author: Mike Shook
DateCreated: 07/14/2018 
DateUpdated: 5/22/2020
Version: 1.1.0

.EXAMPLE
    .\FolderListBuild.ps1 -QueryPath "C:\FolderToList" -OutputPath "C:\FolderToPutListIn"

#>

param (                        
    [string[]] $QueryPath = "$home\Documents", `
    [string[]] $OutputPath = "$home\Desktop"
)

$QueryPathClean = $QueryPath.Split("\",[System.StringSplitOptions]::RemoveEmptyEntries) -join '\' -replace '`',''

$folder_path = $QueryPathClean.Split("\")[-1]
$root_path = $QueryPathClean.Substring(0,$QueryPathClean.Length-$folder_path.Length)
$root_path = $root_path.Split("\",[System.StringSplitOptions]::RemoveEmptyEntries) -join '\'

$folders_file_final_path = "$OutputPath\FolderListBuild_$folder_path"
$folders_file_temp_path = "$folders_file_final_path\temp"
$folders_file_temp_full = "$folders_file_temp_path\folders.csv"

Write-Output "$(Get-Date): Start"
Write-Output "$(Get-Date): Query Path: $QueryPath"
Write-Output "$(Get-Date): Query Path Clean: $QueryPathClean"
Write-Output "$(Get-Date): Output Path: $OutputPath"
Write-Output "$(Get-Date): Root Path: $root_path"
Write-Output "$(Get-Date): Folder: $folder_path"

Write-Output "$(Get-Date): Create folders if they don't exist"

if (!(Test-Path $folders_file_final_path))
{
  New-Item -ItemType Directory -Force -Path $folders_file_final_path
}

if (!(Test-Path $folders_file_temp_path))
{
  New-Item -ItemType Directory -Force -Path $folders_file_temp_path
}

$folders_stream = New-Object IO.StreamWriter $folders_file_temp_full

Write-Output "$(Get-Date): Open Temp Folders File: ""$folders_file_temp_full"""

Write-Output "$(Get-Date): Get Root Information for ""$root_path\$folder_path"""
$result_root = Get-ChildItem -LiteralPath "$root_path\" -Filter "$folder_path" -Directory `
    | Select-Object FullName, `
        @{Name="FileCount";Expression={(Get-ChildItem -LiteralPath $_.FullName -File | Measure-Object).Count }}, `
        @{Name="DirectoryCount";Expression={(Get-ChildItem -LiteralPath $_.FullName -Directory | Measure-Object).Count }} `
    | ConvertTo-Csv -NoTypeInformation

Write-Output "$(Get-Date): Output Root Information for ""$root_path\$folder_path"""
$result_root | ForEach-Object { $folders_stream.WriteLine($_) }

Write-Output "$(Get-Date):   Get Children of Root ""$root_path\$folder_path"""
$result_children = Get-ChildItem -LiteralPath "$root_path\$folder_path" -Name -Directory

Write-Output "$(Get-Date):   Loop Children of Root ""$root_path\$folder_path"""
$result_children | ForEach-Object {
    Write-Output "$(Get-Date):     Get Folder Information for ""$root_path\$folder_path\$_"""
    $result_folder = Get-ChildItem -LiteralPath "$root_path\$folder_path" -Filter $_ -Directory `
        | Select-Object FullName, `
            @{Name="FileCount";Expression={(Get-ChildItem -LiteralPath $_.FullName -File | Measure-Object).Count }}, `
            @{Name="DirectoryCount";Expression={(Get-ChildItem -LiteralPath $_.FullName -Directory | Measure-Object).Count }} `
        | ConvertTo-Csv -NoTypeInformation `
        | Select-Object -Skip 1 

    Write-Output "$(Get-Date):       Output Folder Information for ""$root_path\$folder_path\$_"""
    $result_folder | ForEach-Object { $folders_stream.WriteLine($_) }

    Write-Output "$(Get-Date):       Get Folder Information for children of ""$root_path\$folder_path\$_"""
    $result = Get-ChildItem -LiteralPath "$root_path\$folder_path\$_" -Directory -Recurse `
        | Select-Object FullName, `
            @{Name='FileCount';Expression={(Get-ChildItem -LiteralPath $_.FullName -File | Measure-Object).Count }}, `
            @{Name='DirectoryCount';Expression={(Get-ChildItem -LiteralPath $_.FullName -Directory | Measure-Object).Count }} `
        | ConvertTo-Csv -NoTypeInformation `
        | Select-Object -Skip 1

    Write-Output "$(Get-Date):         Output Folder Information for children of ""$root_path\$folder_path\$_"""
    $result | ForEach-Object { $folders_stream.WriteLine($_) }
}

Write-Output "$(Get-Date):   Close Temp Folders File"
$folders_stream.Close()
$folders_stream.Dispose()

Write-Output "$(Get-Date):   Copy Temp Folders File to Final"
Copy-Item -LiteralPath $folders_file_temp_full -Destination $folders_file_final_path -Force

Write-Output "$(Get-Date):   Delete Temp Folder"
Remove-Item -LiteralPath $folders_file_temp_path -Recurse -Force

Write-Output "$(Get-Date): Finish"

GetScheduledTasks

This script uses the Schedule.Service COM-object to query a list of remote computers in order to gather a formatted list of properties of the task.

<#    
.SYNOPSIS   
Script that returns scheduled tasks from a list of computers

.DESCRIPTION 
This script uses the Schedule.Service COM-object to query a list of remote computers in order to gather a formatted list of properties of the task.

.PARAMETER ComputerNames
The computers that will be queried by this script, local administrative permissions are required to query this information

.CREDITS
https://gallery.technet.microsoft.com/scriptcenter/Get-Scheduled-tasks-from-3a377294
https://gallery.technet.microsoft.com/scriptcenter/Ping-Multiple-Servers-ba915a7c
https://techibee.com/powershell/powershell-get-scheduled-tasks-list-from-windows-72008-computers/1647

.NOTES   
Name: GetScheduledTasks.ps1
Author: Mike Shook
DateCreated: 02/04/2020 
DateUpdated: 02/04/2020
Version: 1.0.0

.EXAMPLE
    .\GetScheduledTasks.ps1 -ComputerNames "server01,server02"

#>

param (                        
    [string[]] $ComputerNames = $env:computername
)

$objNotFound = New-Object PSObject

#function to get all scheduled task folder details.
function Get-TaskSubFolders {
    [CmdletBinding()]
    param(
        $FolderRef
    )
    $ArrFolders = @()
    try {
        $folders = $folderRef.GetFolders(1)
        if ($folders) {
            foreach ($folder in $folders) {
                $ArrFolders = $ArrFolders + $folder
                if ($folder.GetFolders(1)) {
                    Get-TaskSubFolders -FolderRef $folder
                }
            }
        }
    } catch {} finally {}
    return $ArrFolders
}

#function to build the error message.
function Return-Error {
    param(
        $computer,
        $type
    )
    Add-Member -InputObject $objNotFound -MemberType NoteProperty -Name ComputerName -Value "$computer ERROR: $type"
    $objNotFound
}

#MAIN 

foreach ($Computer in $ComputerNames) {
    if (Test-Connection -ComputerName $Computer -Count 2 -Quiet) {
        $SchService = New-Object -ComObject Schedule.Service
        $ErrorActionPreference = "SilentlyContinue"
        $SchService.Connect($Computer)
        $ErrorActionPreference = "Continue"
        if ($SchService.Connected) {            
            $Rootfolder = $SchService.GetFolder("\")
            $folders = @($RootFolder)
            $folders += Get-TaskSubFolders -FolderRef $RootFolder
            $foldersCount = $folders | Measure-Object
            if ($foldersCount.Count -gt 1) {
                foreach ($folder in $folders) {
                    $tasks = $folder.gettasks(1)
                    $tasks | Select-Object @{ Name = 'ComputerName'; Expression = { ($SchService.TargetServer) } },`
                         @{ Name = 'TaskName'; Expression = { ($_.Name) } },`
                         @{ Name = 'TaskFolder'; Expression = { ($Folder.Path) } },`
                         @{ Name = 'State'; Expression = { switch ($_.State) { 0 { 'Unknown' } 1 { 'Disabled' } 2 { 'Queued' } 3 { 'Ready' } 4 { 'Running' } Default {'Unknown'} } } },`
                         @{ Name = 'IsEnabled'; Expression = { ($_.Enabled) } },`
                         LastRunTime,`
                         LastTaskResult,`
                         NumberOfMissedRuns,`
                         NextRunTime,`
                         Definition,`
                         @{ Name = 'RegistrationInfo_Author'; Expression = { ([xml]$_.xml).Task.RegistrationInfo.Author } },`
                         @{ Name = 'RegistrationInfo_Date'; Expression = { ([xml]$_.xml).Task.RegistrationInfo.Date } },`
                         @{ Name = 'RegistrationInfo_Description'; Expression = { ([xml]$_.xml).Task.RegistrationInfo.Description } },`
                         @{ Name = 'UserId'; Expression = { ([xml]$_.xml).Task.Principals.Principal.UserID} },`
                         @{ Name = 'Triggers'; Expression = { ([xml]$_.Xml).Task.Triggers.InnerXml } },`
                         @{ Name = 'Actions'; Expression = { ([xml]$_.Xml).Task.Actions.InnerXml } },`
                         @{ Name = 'Xml'; Expression = { ($_.Xml) } }
                }
            } else {
                Return-Error $SchService.TargetServer "Can't retrieve Scheduled Tasks"
            }
        } else {
            Return-Error $Computer "Can't connect"
        }
    } else {
        Return-Error $Computer "Can't ping"
    }
}

JsonToCsv

This script converts a JSON file into a PowerShell object, then retreives desired values from the members of a sub-object.

<#    
.SYNOPSIS   
Script that converts a specific JSON file to a CSV file of the same name.

.DESCRIPTION 
This script converts a JSON file into a PowerShell object, then retrieves desired values from the members of a sub-object.
Also, JSON escaped codes for newline characters are replaced by their literal strings so that Export-Csv doesn't actually put newline characters in the output.

.PARAMETER JsonFile
The file that will be converted by this script

.NOTES   
Name: JsonToCsv.ps1
Author: Mike Shook
Date Created: 07/12/2015 
Date Updated: 06/27/2020
Version: 1.2.0

.EXAMPLE
    .\JsonToCsv.ps1 "C:\data_file.json"

#>

param (                        
    [string[]] $JsonFile = "$home\Desktop\data_file.json"
)

$CsvFile = $JsonFile -replace '.json', '.csv'

Remove-Item -Path $CsvFile -Force -ErrorAction SilentlyContinue

ForEach ($object in (Get-Content -Path $JsonFile -Raw | ConvertFrom-Json).reflections) {
    $object | select @{ Name = 'data_server_http_accept'; Expression = {$object.data.server.http_accept -replace '[\r]','\r' -replace '[\n]','\n' }},`
        @{ Name = 'data_server_http_accept_encoding'; Expression = {$object.data.server.http_accept_encoding -replace '[\r]','\r' -replace '[\n]','\n' }},`
        @{ Name = 'data_server_http_accept_language'; Expression = {$object.data.server.http_accept_language -replace '[\r]','\r' -replace '[\n]','\n' }},`
        @{ Name = 'data_server_https'; Expression = {$object.data.server.https -replace '[\r]','\r' -replace '[\n]','\n' }},`
        @{ Name = 'data_server_remote_addr'; Expression = {$object.data.server.remote_addr -replace '[\r]','\r' -replace '[\n]','\n' }},`
        @{ Name = 'data_server_request_method'; Expression = {$object.data.server.request_method -replace '[\r]','\r' -replace '[\n]','\n' }},`
        @{ Name = 'data_server_request_time'; Expression = {$object.data.server.request_time -replace '[\r]','\r' -replace '[\n]','\n' }},`
        @{ Name = 'data_server_server_name'; Expression = {$object.data.server.server_name -replace '[\r]','\r' -replace '[\n]','\n' }},`
        @{ Name = 'data_server_server_port'; Expression = {$object.data.server.server_port -replace '[\r]','\r' -replace '[\n]','\n' }},`
        @{ Name = 'data_server_server_protocol'; Expression = {$object.data.server.server_protocol -replace '[\r]','\r' -replace '[\n]','\n' }},`
        @{ Name = 'links_about'; Expression = {$object.links.about -replace '[\r]','\r' -replace '[\n]','\n' }},`
        @{ Name = 'links_openapi'; Expression = {$object.links.openapi -replace '[\r]','\r' -replace '[\n]','\n' }},`
        @{ Name = 'links_swaggerhub'; Expression = {$object.links.swaggerhub -replace '[\r]','\r' -replace '[\n]','\n' }},`
        @{ Name = 'links_wadl'; Expression = {$object.links.wadl -replace '[\r]','\r' -replace '[\n]','\n' }},`
        @{ Name = 'links_describedby'; Expression = {$object.links.describedby -replace '[\r]','\r' -replace '[\n]','\n' }}`
     | Export-Csv -Path "$CsvFile" -NoTypeInformation -Append -Delimiter ',' -Encoding UTF8
}

XmlToCsv

This script converts a XML file into a PowerShell object, then retreives desired values from the members of a sub-object.

<#    
.SYNOPSIS   
Script that converts a specific XML file to a CSV file of the same name.

.DESCRIPTION 
This script converts a XML file into a PowerShell object, then retrieves desired values from the members of a sub-object.
Also, XML newline characters are replaced by their literal strings so that Export-Csv doesn't actually put newline characters in the output.

.PARAMETER XmlFile
The file that will be converted by this script

.NOTES   
Name: XmlToCsv.ps1
Author: Mike Shook
Date Created: 05/17/2015 
Date Updated: 06/27/2020
Version: 1.2.0

.EXAMPLE
    .\XmlToCsv.ps1 "C:\data_file.xml"

#>

param (                        
    [string[]] $XmlFile = "$home\Desktop\data_file.xml"
)

$CsvFile = $XmlFile -replace '.xml', '.csv'

Remove-Item -Path $CsvFile -Force -ErrorAction SilentlyContinue

[xml]$XmlDocument = Get-Content -Path $XmlFile

ForEach ($object in $XmlDocument.reflections) {
    $object | select @{ Name = 'data_server_http_accept'; Expression = {$object.data.server.http_accept -replace '[\r]','\r' -replace '[\n]','\n' }},`
        @{ Name = 'data_server_http_accept_encoding'; Expression = {$object.data.server.http_accept_encoding -replace '[\r]','\r' -replace '[\n]','\n' }},`
        @{ Name = 'data_server_http_accept_language'; Expression = {$object.data.server.http_accept_language -replace '[\r]','\r' -replace '[\n]','\n' }},`
        @{ Name = 'data_server_https'; Expression = {$object.data.server.https -replace '[\r]','\r' -replace '[\n]','\n' }},`
        @{ Name = 'data_server_remote_addr'; Expression = {$object.data.server.remote_addr -replace '[\r]','\r' -replace '[\n]','\n' }},`
        @{ Name = 'data_server_request_method'; Expression = {$object.data.server.request_method -replace '[\r]','\r' -replace '[\n]','\n' }},`
        @{ Name = 'data_server_request_time'; Expression = {$object.data.server.request_time -replace '[\r]','\r' -replace '[\n]','\n' }},`
        @{ Name = 'data_server_server_name'; Expression = {$object.data.server.server_name -replace '[\r]','\r' -replace '[\n]','\n' }},`
        @{ Name = 'data_server_server_port'; Expression = {$object.data.server.server_port -replace '[\r]','\r' -replace '[\n]','\n' }},`
        @{ Name = 'data_server_server_protocol'; Expression = {$object.data.server.server_protocol -replace '[\r]','\r' -replace '[\n]','\n' }},`
        @{ Name = 'links_about'; Expression = {$object.links.about -replace '[\r]','\r' -replace '[\n]','\n' }},`
        @{ Name = 'links_openapi'; Expression = {$object.links.openapi -replace '[\r]','\r' -replace '[\n]','\n' }},`
        @{ Name = 'links_swaggerhub'; Expression = {$object.links.swaggerhub -replace '[\r]','\r' -replace '[\n]','\n' }},`
        @{ Name = 'links_wadl'; Expression = {$object.links.wadl -replace '[\r]','\r' -replace '[\n]','\n' }},`
        @{ Name = 'links_describedby'; Expression = {$object.links.describedby -replace '[\r]','\r' -replace '[\n]','\n' }}`
     | Export-Csv -Path "$CsvFile" -NoTypeInformation -Append -Delimiter ',' -Encoding UTF8
}