PSGubbins.psm1
# This PSM1 compiled with psake 2020/11/01 20:28:21 # PSGubbins\Source\Functions\Get-Cpl.ps1 function Get-Cpl { <# .SYNOPSIS Finds any .cpl files in a given location. .DESCRIPTION Performs a recursive search to find all unique .cpl files in a given location, and return the name and the associated file description. .PARAMETER Path The path which will be searched. By default this is 'C:\Windows\System32' .EXAMPLE Get-Cpl -Path "C:\" Name Description ---- ----------- appwiz.cpl Shell Application Manager bthprops.cpl Bluetooth Control Panel Applet CmiCnfgp.cpl ConfigPanel DLL desk.cpl Desktop Settings Control Panel Firewall.cpl Windows Defender Firewall Control Panel DLL Launching Stub FlashPlayerCPLApp.cpl hdwwiz.cpl Add Hardware Control Panel Applet igfxcpl.cpl igfxcpl Module inetcpl.cpl intl.cpl Control Panel DLL irprops.cpl Infrared Control Panel Applet joy.cpl Game Controllers Control Panel Applet main.cpl Mouse and Keyboard Control Panel Applets MLCFG32.CPL Microsoft Mail Configuration Library mmsys.cpl Audio Control Panel ncpa.cpl Network Connections Control-Panel Stub powercfg.cpl Power Management Configuration Control Panel Applet sapi.cpl Speech UX Control Panel sysdm.cpl TabletPC.cpl Tablet PC Control Panel telephon.cpl Telephony Control Panel timedate.cpl Time Date Control Panel Applet wscui.cpl Security and Maintenance .INPUTS String .OUTPUTS PSCUstomObject #> [CmdletBinding()] [Alias("Get-ControlPanelApplet")] [OutputType([PSCustomObject])] param ( [Parameter(Mandatory = $False, Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True, HelpMessage = "The file path to search for CPL files.")] [ValidateScript( { if (Test-Path $_) { $True } else { throw "The specified location could not be found." } } )] [alias("FullName", "FilePath")] [string] $Path = "C:\Windows\System32" ) try { if (Test-Path -Path $Path) { $SearchSplat = @{ Path = $Path Include = "*.cpl" Recurse = $True Force = $True ErrorAction = "SilentlyContinue" } $Files = Get-ChildItem @SearchSplat | Sort-Object -Property "Name" -Unique forEach ($File in $Files) { [PSCustomObject]@{ Name = $File.Name Description = $File.VersionInfo.FileDescription Path = $File.FullName } } } else { Write-Warning -Message "The provided path is inaccessible ($Path)" } } catch { $PSCmdlet.ThrowTerminatingError($_) } } # PSGubbins\Source\Functions\Get-Msc.ps1 function Get-Msc { <# .SYNOPSIS Finds any .msc files (MMC snap-ins) in a specified location. .DESCRIPTION Performs a recursive search to find all unique .msc files in a given location, and return the name and the associated file description. .PARAMETER Path The path to be searched for snap-in files. .EXAMPLE Get-Msc -Path "C:\" .INPUTS String .OUTPUTS PSCUstomObject #> [CmdletBinding()] [Alias("Get-MMCSnapIn")] [OutputType([PSCustomObject])] param ( [Parameter(Mandatory = $False, Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True, HelpMessage = "The file path to search for CPL files.")] [ValidateScript( { if (Test-Path $_) { $True } else { throw "The specified location could not be found." } } )] [alias("FullName", "FilePath")] [string] $Path = "C:\Windows\System32" ) try { if (Test-Path -Path $Path) { $SearchSplat = @{ Path = $Path Include = "*.msc" Recurse = $True ErrorAction = "SilentlyContinue" } $Files = Get-ChildItem @SearchSplat | Sort-Object -Property "Name" -Unique forEach ($File in $Files) { [PSCustomObject]@{ Name = $File.Name Path = $File.FullName } } } else { Write-Warning -Message "The provided path is inaccessible ($Path)" } } catch { $PSCmdlet.ThrowTerminatingError($_) } } # PSGubbins\Source\Functions\New-Password.ps1 function New-Password { <# .SYNOPSIS Creates one or more password/passphrase from custom or pre-defined lists of words. .DESCRIPTION Creates one or more password/passphrase from custom or pre-defined lists of words, with the option of specifying minimum or maximum lengths. .PARAMETER Count The number of passwords to generate. .PARAMETER Long Determines whether longer passwords will be generated by using a third list of words. .PARAMETER MinimumLength Determines the minimum accepted length of the generated password(s). .PARAMETER MaximumLength Determines the maximum accepted length of the generated password(s). .PARAMETER FirstDictionary The first group of words to be used when generating the password. .PARAMETER SecondDictionary The second group of words to be used when generating the password. .PARAMETER ExtraDictionary The third group of words to be used when generating the password. .EXAMPLE New-Password Generates a new password. .EXAMPLE New-Password -Count 10 -Long Generates 10 long passwords. .EXAMPLE New-Password -Count 10 -MinimumLength 16 Generates 10 passwords at least 16 characters long. .INPUTS String, Integer .OUTPUTS String #> [CmdletBinding(ConfirmImpact = "Low", SupportsShouldProcess = $False)] [Alias("New-Passphrase")] [OutputType([String])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "", Justification = "This does generate something new but it does not change state.")] param ( [Parameter(Mandatory = $False, Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True, HelpMessage = "The number of passwords to generate")] [Alias('Number')] [int] $Count = 1, [Parameter(Mandatory = $False, HelpMessage = "Determines the complexity of the password")] [Alias('Extended', 'Complex')] [switch] $Long = $False, [Parameter(Mandatory = $False, HelpMessage = "Determines the minimum accepted length of the password")] [int] $MinimumLength = $Null, [Parameter(Mandatory = $False, HelpMessage = "Determines the maximum accepted length of the password")] [int] $MaximumLength = $Null, [Parameter(Mandatory = $False, HelpMessage = "The first group of words to be used when generating the password - adjectives by default")] [string[]] $FirstDictionary = @('Adorable', 'Adventurous', 'Aggressive', 'Agreeable', 'Alert', 'Alive', 'Amused', 'Angry', 'Annoyed', 'Annoying', 'Anxious', 'Arrogant', 'Ashamed', 'Attractive', 'Average', 'Awesome', 'Awful', 'Bad', 'Basic', 'Beautiful', 'Better', 'Bewildered', 'Bitter', 'Black', 'Bloody', 'Blue', 'Blue-eyed', 'Blushing', 'Bored', 'Brainy', 'Brave', 'Breakable', 'Bright', 'Busy', 'Calm', 'Careful', 'Cautious', 'Charming', 'Cheerful', 'Clean', 'Clear', 'Clever', 'Cloudy', 'Clumsy', 'Colorful', 'Combative', 'Comfortable', 'Concerned', 'Condemned', 'Confused', 'Cooperative', 'Correct', 'Courageous', 'Crazy', 'Creepy', 'Crowded', 'Cruel', 'Curious', 'Cute', 'Dangerous', 'Dark', 'Dead', 'Defeated', 'Defiant', 'Delightful', 'Depressed', 'Determined', 'Different', 'Difficult', 'Disgusted', 'Distinct', 'Disturbed', 'Divine', 'Dizzy', 'Doubtful', 'Drab', 'Dull', 'Eager', 'Easy', 'Elated', 'Elegant', 'Embarrassed', 'Enchanting', 'Encouraging', 'Energetic', 'Enraged', 'Enthusiastic', 'Envious', 'Evil', 'Excited', 'Expensive', 'Exuberant', 'Fair', 'Faithful', 'Famous', 'Fancy', 'Fantastic', 'Fast', 'Fat', 'Fierce', 'Filthy', 'Fine', 'Foolish', 'Fragile', 'Frail', 'Frantic', 'Friendly', 'Frightened', 'Funny', 'Gentle', 'Gifted', 'Glamorous', 'Gleaming', 'Glorious', 'Good', 'Gorgeous', 'Graceful', 'Great', 'Grieving', 'Grotesque', 'Grumpy', 'Guilty', 'Handsome', 'Handy', 'Happy', 'Healthy', 'Helpful', 'Helpless', 'Hilarious', 'Homeless', 'Homely', 'Horrible', 'Huge', 'Hungry', 'Hurt', 'Ill', 'Important', 'Impossible', 'Inexpensive', 'Innocent', 'Inquisitive', 'Intelligent', 'Irritated', 'Itchy', 'Jealous', 'Jittery', 'Jolly', 'Joyous', 'Just', 'Kind', 'Lazy', 'Light', 'Lively', 'Lonely', 'Long', 'Lovely', 'Lucky', 'Magnificent', 'Massive', 'Misty', 'Modern', 'Moral', 'Morose', 'Motionless', 'Muddy', 'Mushy', 'Mysterious', 'Nasty', 'Naughty', 'Nervous', 'Nice', 'Nutty', 'Obedient', 'Obnoxious', 'Odd', 'Open', 'Outrageous', 'Outstanding', 'Panicky', 'Perfect', 'Plain', 'Pleasant', 'Poised', 'Poor', 'Powerful', 'Precious', 'Prickly', 'Proud', 'Psyched', 'Putrid', 'Puzzled', 'Quaint', 'Rapid', 'Real', 'Relieved', 'Repulsive', 'Resourceful', 'Rich', 'Righteous', 'Sad', 'Scary', 'Selfish', 'Shiny', 'Shy', 'Silly', 'Sinful', 'Sleepy', 'Smart', 'Smiling', 'Smoggy', 'Sore', 'Sparkling', 'Splendid', 'Spotless', 'Stormy', 'Strange', 'Strong', 'Stupid', 'Successful', 'Super', 'Talented', 'Tame', 'Tasty', 'Tender', 'Tense', 'Terrible', 'Thankful', 'Thoughtful', 'Thoughtless', 'Tiny', 'Tired', 'Tough', 'Troubled', 'Ugliest', 'Ugly', 'Uninterested', 'Unsightly', 'Unusual', 'Upright', 'Upset', 'Uptight', 'Vast', 'Vengeful', 'Vexed', 'Victorious', 'Violent', 'Vivacious', 'Wandering', 'Weary', 'Wicked', 'Wild', 'Witty','Worried', 'Worrisome', 'Wrathful', 'Wrong', 'Zany', 'Zealous'), [Parameter(Mandatory = $False, HelpMessage = "The second group of words to be used when generating the password - animal names by default")] [string[]] $SecondDictionary = @('Alligators', 'Apes', 'Baboons', 'Badgers', 'Beavers', 'Cats', 'Cheetahs', 'Chipmunks', 'Coyotes', 'Crocodiles', 'Crocs', 'Dinosaurs', 'Dogs', 'Dolphins', 'Ducks', 'Ferrets', 'Fish', 'Fleas', 'Foxes', 'Gators', 'Geese', 'Giraffes', 'Goats', 'Hares', 'Honey Badgers', 'Horses', 'Leopards', 'Lions', 'Meerkats', 'Mice', 'Monkeys', 'Moose', 'Pandas', 'Penguins', 'Rabbits', 'Raccoons', 'Rats', 'Reindeer', 'Sharks', 'Sheep', 'Squirrels', 'Swans', 'Tigers', 'Tortoises', 'Turtles', 'Weasels', 'Wolves', 'Zebras'), [Parameter(Mandatory = $False, HelpMessage = "The third group of words to be used when generating the password - modifiers by default")] [string[]] $ExtraDictionary = @("Abhorrently", "Abnormally", "Absurdly", "Acceptably", "Accordingly", "Adorably", "Amazingly", "Artfully", "Creatively", "Extremely", "Incredibly", "Infinitely", "Mad", "Moderately", "Particularly", "Pleasingly", "Proper", "Really", "Reasonably", "Somewhat", "Strikingly", "Sufficiently", "Super", "Supremely", "Totally", "Tremendously", "Truly", "Very", "Well", "Wicked") ) BEGIN { if ($PSBoundParameters.ContainsKey("Debug")) { $DebugPreference = "Continue" } Write-Debug -Message "BEGIN Block" if ($Long) { Write-Verbose -Message "The 'Long' parameter has been used. All dictionaries will be used when generating the password(s)." } if ($MinimumLength) { Write-Verbose -Message "The minimum allowed length has been set as $MinimumLength." } if ($MaximumLength) { Write-Verbose -Message "The maximum allowed length has been set as $MaximumLength." } } PROCESS { Write-Debug -Message "PROCESS Block" for ($i = 0; $i -lt $Count) { $Random = (Get-Random -Minimum 1 -Maximum 10000) # Define the separator to appear between words. if ($Random % 2 -eq 0) { [string] $Separator = "-" } else { [string] $Separator = "_" } if (($Long -eq $True) -or ($Random -ge 4999)) { $RequiredDictionaries = @($ExtraDictionary, $FirstDictionary, $SecondDictionary) Write-Verbose -Message "Creating 'long' password." } else { $RequiredDictionaries = @($FirstDictionary, $SecondDictionary) } # Start generating the actual password. try { $PassPhrase = $Null Write-Debug -Message "Generating number to start password." [string] $PassPhrase = Get-Random -Minimum 2 -Maximum 999 -ErrorAction "Stop" [string] $Password = $PassPhrase + $Separator } catch { $PSCmdlet.ThrowTerminatingError($_) } # Start adding words! forEach ($Dictionary in $RequiredDictionaries) { $PassPhrase = $Null try { Write-Verbose -Message "Retrieving word." $DictionaryLength = ($Dictionary).Length $PassPhrase = $Dictionary[(Get-Random -Minimum 0 -Maximum $DictionaryLength -ErrorAction "Stop")] Write-Debug -Message "Determining case." [string] $PassPhrase = if ((Get-Random -Minimum 0 -Maximum 10) -ge 5) { $PassPhrase.ToUpper() } else { $PassPhrase.ToLower() } Write-Debug -Message "Adding word ($PassPhrase) to password." [string] $Password += $PassPhrase + $Separator } catch { $PSCmdlet.ThrowTerminatingError($_) } } if ($Null -ne $Password) { Write-Debug -Message "Cleaning up final separator." $Password = $Password -replace "$Separator$", "" # Removes final 'separator' added to the end of the password. if ((-not ($MinimumLength)) -and (-not ($MaximumLength))) { # If we're not checking the length, tick over the counter and output the password. Write-Debug -Message "No length validation required." $i ++ $Password } else { if (($MinimumLength) -and (-not ($MaximumLength))) { Write-Debug -Message "Validating against minimum length only." if ($Password.Length -ge $MinimumLength) { Write-Verbose -Message "The password is $($Password.Length) characters long." $i ++ $Password } } elseif (($MaximumLength) -and (-not ($MinimumLength))) { Write-Debug -Message "Validating against maximum length only." if ($Password.Length -le $MaximumLength) { Write-Verbose -Message "The password is $($Password.Length) characters long." $i ++ $Password } } elseif (($MinimumLength) -and ($MaximumLength)) { Write-Debug -Message "Validating against minimum and maximum length." if (($Password.Length -ge $MinimumLength) -and ($Password.Length -le $MaximumLength)) { Write-Verbose -Message "The password is $($Password.Length) characters long." $i ++ $Password } } } } else { Write-Warning -Message "No password was generated - that shouldn't have happened!" } } } END { Write-Debug -Message "END Block" } } # PSGubbins\Source\Functions\New-RDPSession.ps1 function New-RdpSession { <# .SYNOPSIS Launches a Remote Desktop connection to specified computer(s). .DESCRIPTION Uses mstsc.exe to launch a Remote Desktop connection to specified computer(s) subject a successful ping. .PARAMETER ComputerName The computer(s) to be connected to. .PARAMETER PassThru Whether or not an object is output to represent each session. .PARAMETER SkipPing Dictates that a successful ping should not be required to attempt connection. .EXAMPLE rdp -ComputerName "dc01", "file01" .EXAMPLE rdp dc01 .EXAMPLE rdp file01 -SkipTest .EXAMPLE rdp 10.0.10.50 .INPUTS Strings .OUTPUTS PSCustomObject (optional) #> [CmdletBinding(ConfirmImpact = "Low", SupportsShouldProcess = $True)] [OutputType("PSCustomObject")] [Alias("rdp")] param ( [Parameter(Mandatory = $True, Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True, HelpMessage = "The computer(s) to RDP to")] [string[]] $ComputerName, [Parameter(Mandatory = $False, Position = 1, HelpMessage = "Whether or not an object is output to represent each session.")] [switch] $PassThru, [Parameter(Mandatory = $False, Position = 2, HelpMessage = "Dictates that a successful ping should not be required to attempt connection.")] [switch] $SkipPing ) BEGIN { if ($PSBoundParameters.ContainsKey("Debug")) { $DebugPreference = "Continue" } Write-Debug -Message "BEGIN Block" } PROCESS { Write-Debug -Message "PROCESS Block" forEach ($Computer in $ComputerName) { Write-Verbose -Message "Pinging '$Computer'" $PingTest = $Null $PingTest = Test-Connection -ComputerName $Computer -Count 2 -ErrorAction "SilentlyContinue" if ($PingTest) { if ($PSCmdlet.ShouldProcess($Computer, "Create new RDP session")) { $RdpSplat = @{ FilePath = "mstsc.exe" ArgumentList = "/v:$Computer" PassThru = $True ErrorAction = "Stop" } try { $Process = Start-Process @RdpSplat if ($PassThru) { [PSCustomObject]@{ ComputerName = $Computer IPv4Address = $PingTest.IPv4Address | Sort-Object -Unique PID = $Process.Id } } } catch { Write-Warning -Message "Problems starting RDP session with '$Computer'" } } } else { Write-Verbose -Message "Ping to '$Computer' failed. Skipping RDP connection." } } } END { Write-Debug -Message "END Block" } } |