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 '$comparisonValue' when the Base data is calculated.
.NOTES
Name: EspnFantasyFootballLineup.ps1
Author: Mike Shook
Version: 1.5.0.7
Version Date: 10/25/2021
Version Notes: CHANGE: Change the comparison value to be calculated using the % Rostered in instead of % Started to overcome issues related to bye week statistics
CHANGE: The Comparsion Value is now using the average of the Projected player points and 3 x their Average points to give more weight to their average
Version: 1.5.0.6
Version Date: 10/2/2021
Version Notes: ADD: Average player points to the Calculated Comparison by Position
ADD: Player's Bye Week to the Calculated Comparison by Position
ADD: Player's Bye Week Alert to the Calculated Lineup if the player has their Bye next week
ADD: Player's acquisition type to the Calculated Comparison by Position
CHANGE: The Comparsion Value is now using the average of the Projected player points and their Average points instead of just Projected
CHANGE: All D/ST players are permanently 'ACTIVE'
Version: 1.4.0.5
Version Date: 9/27/2021
Version Notes: ADD: Added Actual total points for mid-week lookups to the Calculated Lineup
Version: 1.3.0.4
Version Date: 9/17/2021
Version Notes: ADD: Actual player points for mid-week lookups to the Calculated Comparison by Position
ADD: The Projected Points is now multiplied by a value based on player position during the Comparison value calculation.
This is done in an attempt to equalize the Comparison value across positions: QB=1, RB=1.5, WR=1.6, TE=2.5, K=3.2, D/ST=3.5
The average of the 2020 top 16 players average fantasy points for each position were used to create the multipliers.
Version: 1.2.0.3
Version Date: 12/13/2020
Version Notes: ADD: Ability to always have locked players marked with where they were when they played
Version: 1.1.0.2
Version Date: 10/21/2020
Version Notes: ADD: Output of the current and new projected total points
Version: 1.0.0.1
Version Date: 9/21/2020
Version Notes: First version
.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
^^
.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 ####################
### Setup Console ##########################################################################################################################
# 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.BufferSize = New-Object System.Management.Automation.Host.size(150, 3000)
$host.UI.RawUI.WindowSize = New-Object System.Management.Automation.Host.size(150, 49)
}
else {
$host.UI.RawUI.BufferSize = New-Object System.Management.Automation.Host.size(150, 3000)
$host.UI.RawUI.WindowSize = New-Object System.Management.Automation.Host.size(150, 39)
}
}
### Get Data ###############################################################################################################################
# Get basic data from ESPN for the current week
Write-Host "Getting basic data for ESPN Fantasy Football..." -ForegroundColor Yellow
$year = Get-Date -Format "yyyy"
$uriLeague = 'https://fantasy.espn.com/apis/v3/games/ffl/seasons/' + $year + '/segments/0/leagues/' + $leagueId
$GetLeagueSession = Invoke-WebRequest -Uri $uriLeague -Method GET -timeoutSec 360 -ErrorAction Stop
$league = $GetLeagueSession.Content | ConvertFrom-Json
$week = $league.scoringPeriodId
# Set paths to all temp files and delete any old ones
$pathRoot = $env:TEMP + '\ESPN_FFL'
[void]( New-Item -ItemType Directory -Force -Path $pathRoot )
$path = $pathRoot + '\ESPN_FFL'
$filePro = $path + '_Pro_Teams.json'
$fileLeague = $path + '_' + $leagueId + '.json'
$fileTeamBase = $path + '_' + $leagueId + '_' + $teamId + '_' + $week
$fileTeam = $fileTeamBase + '.json'
$fileTeamCsv = $fileTeamBase + '_1_team.csv'
$fileComparisonCsv = $fileTeamBase + '_2_comparison.csv'
$fileSortedCsv = $fileTeamBase + '_3_sorted.csv'
$fileStartCsv = $fileTeamBase + '_4_start.csv'
$fileChangeCsv = $fileTeamBase + '_5_change.csv'
$fileCollection = $path + '*.*'
$currentProjected = 0
$newProjected = 0
$actual = 0
$weeksBack = 3
Remove-Item -Path $fileCollection -ErrorAction SilentlyContinue
# Write out the basic json data
$GetLeagueSession.Content | Out-File $fileLeague
# Get data from ESPN for pro teams
Write-Host "Getting data for the Professional Teams..." -ForegroundColor Yellow
$uriPro = 'https://fantasy.espn.com/apis/v3/games/ffl/seasons/' + $year + '?view=proTeamSchedules_wl'
$GetProSession = Invoke-WebRequest -Uri $uriPro -Method GET -timeoutSec 360 -ErrorAction Stop
$GetProSession.Content | Out-File $filePro
$jsonPro = $GetProSession.Content | ConvertFrom-Json
$hashProBye = @{}
foreach ($team in $jsonPro.settings.proTeams) {
$hashProBye[$team.id] = $team.byeWeek
}
# Get the stats information from ESPN
Write-Host "Getting data for Team $teamId in League $leagueId..." -ForegroundColor Yellow
$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 $fileTeam
$json = $GetSession.Content | ConvertFrom-Json
### Calculate ##############################################################################################################################
# Get the team information
$team = $json.teams[$teamId - 1]
$teamName = $team.location + ' ' + $team.nickname
$teamName = $teamName.ToUpper()
# 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 = 'ShortName'; Expression = { ($entry.playerPoolEntry.player.firstName).substring(0,1) + '. ' + $entry.playerPoolEntry.player.lastName } }, `
@{ Name = 'Slot'; Expression = { $entry.lineupSlotId } }, `
@{ Name = 'Aquisition'; Expression = { $entry.acquisitionType } }, `
@{ Name = 'Locked'; Expression = { $entry.playerPoolEntry.lineupLocked } }, `
@{ Name = 'Bye'; Expression = { $hashProBye[$entry.playerPoolEntry.player.proTeamId] } }, `
@{ 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 = 'Multiplier'; Expression = {
Switch ([int]$entry.playerPoolEntry.player.defaultPositionId) {
{ ($_ -eq 1) } { '1'; Break }
{ ($_ -eq 2) } { '1.5'; Break }
{ ($_ -eq 3) } { '1.6'; Break }
{ ($_ -eq 4) } { '2.5'; Break }
{ ($_ -eq 5) } { '3.2'; Break }
{ ($_ -eq 16) } { '3.5'; Break }
Default { '1' }
}
}
}, `
@{ Name = 'defaultPositionId'; Expression = { [int]$entry.playerPoolEntry.player.defaultPositionId } }, `
@{ Name = 'injured'; Expression = { $entry.playerPoolEntry.player.injured } }, `
@{ Name = 'Status'; Expression = {
If ( [int]$entry.playerPoolEntry.player.defaultPositionId -eq 16 ) {
'ACTIVE'
} else {
$entry.playerPoolEntry.player.injuryStatus
}
}
}, `
@{ Name = 'Started'; Expression = { [single]$entry.playerPoolEntry.player.ownership.percentStarted } }, `
@{ Name = 'Rostered'; Expression = { [single]$entry.playerPoolEntry.player.ownership.percentOwned } }, `
@{ Name = 'Ranking'; Expression = { [int]$entry.playerPoolEntry.ratings.'0'.positionalRanking } }, `
@{ Name = 'Points'; Expression = {
ForEach ($stat in $entry.playerPoolEntry.player.stats) {
If ( ( $stat.seasonId -eq $year ) -and ( $stat.scoringPeriodId -eq $week ) -and ( $stat.statSourceId -eq '1' ) ) {
$stat.appliedTotal
}
}
}
}, `
@{ Name = 'Actual'; Expression = {
ForEach ($stat in $entry.playerPoolEntry.player.stats) {
If ( ( $stat.seasonId -eq $year ) -and ( $stat.scoringPeriodId -eq $week ) -and ( $stat.statSourceId -eq '0' ) ) {
$stat.appliedTotal
}
}
}
}, `
@{ Name = 'ActualAvg'; Expression = {
ForEach ($stat in $entry.playerPoolEntry.player.stats) {
If ( ( $stat.seasonId -eq $year ) -and ( $stat.scoringPeriodId -eq '0' ) -and ( $stat.statSourceId -eq '0' ) ) {
[single]$stat.appliedAverage
}
}
}
}`
| Export-Csv -Path $fileTeamCsv -NoTypeInformation -Append -Force
}
# Load the base data, calculate the comparison, and write it out to a temp file
$comparisonTable = Import-Csv -Path $fileTeamCsv
ForEach ($player in $comparisonTable) {
If ( [int]$player.slot -ne 20 ) {
$currentProjected = [single]$currentProjected + [single]$player.Points
$actual = [single]$actual + [single]$player.Actual
}
$comparisonValue = ( ( ( [single]$player.Points + ( [single]$player.ActualAvg * 3 ) ) / 4 ) * [single]$player.Multiplier) + ([single]$player.Rostered / 6) - ( [single]$player.Ranking / 8)
$comparisonOutValue = ( [single]$player.ActualAvg * [single]$player.Multiplier) + ([single]$player.Rostered / 6) - ( [single]$player.Ranking / 8)
$player | Select-Object *, `
@{ Name = 'Projected'; Expression = { [single]$currentProjected } }, `
@{ Name = 'ComparisonOrig'; Expression = { If ( [single]$player.Points -ne '0' -AND $player.injured -eq $False ) { $comparisonValue } Else { $comparisonOutValue } } }, `
@{ Name = 'Comparison'; Expression = { If ( $player.Locked -eq $True -AND $player.Slot -ne '20' ) { [single]'100' + $comparisonValue } ElseIf ( $player.Locked -eq $True -AND $player.Slot -eq '20' ) { [single]'-100' + $comparisonValue } ElseIf ( [single]$player.Bye -eq [single]$week ) { [single]'-100' + $comparisonValue } ElseIf ( [single]$player.Points -ne '0' -AND $player.injured -eq $False ) { $comparisonValue } 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' }
}
}, `
@{ Name = 'Bye Alert'; Expression = {
if ([int]$_.Bye -eq ( [int]$week + 1 ) ) { 'NEXT WEEK' }
if ([int]$_.Bye -eq ( [int]$week ) ) { 'NOW' }
else { '' }
}
}`
| 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 )
### Output #################################################################################################################################
Clear-Host
# Output the Calculated Comparison report
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 ''
Write-Host 'The Comparison value is calculated using this formula:' -ForegroundColor Cyan
Write-Host ' ( ( ( "Projected" + ( "Average" * 3 ) ) / 4 ) * "Multiplier" ) + ( "% Rostered" / 6 ) - ( "Position Rank" / 8 )' -ForegroundColor Cyan
Write-Output $finalTable | Sort-Object -Property @{ Expression = { [int]$_.defaultPositionId }; Descending = $False }, `
@{ Expression = { [single]$_.Comparison }; Descending = $True }`
| Format-Table -GroupBy Position -Wrap -Property @{Name = 'Name'; Expression = { $_.ShortName } }, `
Aquisition, `
@{Name = 'Injury Status'; Expression = { $_.Status } }, `
@{Name = 'Bye'; Expression = { $_.Bye } }, `
@{Name = 'Projected'; Expression = { [math]::Round($_.Points, 2) } }, `
@{Name = 'Actual'; Expression = { [math]::Round($_.Actual, 2) } }, `
@{Name = 'Average'; Expression = { [math]::Round($_.ActualAvg, 2) } }, `
Multiplier, `
@{Name = '% Started'; Expression = { [math]::Round($_.Started, 2) } }, `
@{Name = '% Rostered'; Expression = { [math]::Round($_.Rostered, 2) } }, `
@{Name = 'Position Rank'; Expression = { [math]::Round($_.Ranking) } }, `
@{Name = 'Comparison'; Expression = { [math]::Round($_.ComparisonOrig, 2) } }, `
'Start ?', `
Change
# Output separator lines
Write-Output ' '
Write-Host $lineThick -ForegroundColor Red
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-Host ' '
Write-Host "↑ Scroll up to see the Calculated Comparison By Position information ↑" -ForegroundColor Cyan
Write-Output ' '
Write-Host "$year WEEK $week CALCULATED LINEUP" -ForegroundColor Green
}
Else {
Write-Host "↑ Scroll up to see the Calculated Comparison By Position information ↑" -ForegroundColor Cyan
Write-Output ' '
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, `
'Bye Alert', `
@{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"
$actual = [math]::Round($actual, 2)
Write-Output "Actual Total: $actual"
Write-Host $lineThin -ForegroundColor Red
### Exit ###################################################################################################################################
# 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"
GetInstalledSoftware
Script that returns the installed software on the local computer and saves the list to a file.
<#
.SYNOPSIS
Script that returns the installed software on the local computer and saves the list to a file.
.DESCRIPTION
This script reads the System Registry to gather a formatted list of installed software,
then displays it and also saves it to a file on the user's desktop.
.NOTES
Name: GetInstalledSoftware.ps1
Author: Mike Shook
DateCreated: 07/11/2021
DateUpdated: 07/11/2021
Version: 1.0.0
.EXAMPLE
.\GetInstalledSoftware.ps1
#>
$savePath = "$env:USERPROFILE\Desktop"
$computerName = "$env:computername"
$listFile = $computerName + "_AllProgramsListFile.txt"
$software = Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* `
| Sort-Object -Property DisplayName `
| Select-Object DisplayName, DisplayVersion, Publisher, InstallDate, InstallSource `
| Format-Table
Write-Output $software
Write-Output $software | Out-File "$savePath\$listFile" -Encoding ASCII
Write-Host " ** $savePath\$listFile SAVED!" -Foreground Green
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
}
ValidateActiveDirectoyPassword
This script validates a user's Active Directory password.
<#
.SYNOPSIS
Script that validates a user's Active Directory password.
.NOTES
Name: ValidateActiveDirectoyPassword.ps1
Author: Mike Shook
Version: 1.0.0.1
Version Date: 07/20/2021
Source: https://serverfault.com/questions/276098/check-if-user-password-input-is-valid-in-powershell-script
#>
#Read credentials
$cred = Get-Credential
$UserName = $cred.username
$Password = $cred.GetNetworkCredential().password
# Get current domain using logged-on user's credentials
$CurrentDomain = "LDAP://" + ([ADSI]"").distinguishedName
$domain = New-Object System.DirectoryServices.DirectoryEntry($CurrentDomain, $UserName, $Password)
if ($domain.name -eq $null) {
write-host "Authentication failed - please verify your username and password."
}
else {
write-host "Successfully authenticated with domain $domain.name"
}