Functions/Functions.ps1

Function Add-DistributionMember {

    <#
    .SYNOPSIS
    -Taylor Lee
    Modified 05172019
 
    .DESCRIPTION
    Add a mailbox or mailboxes to a distribution group. Wildcards can be used to add the whole orginization to a distribution group.
 
    .NOTES
    Requires the microsoft exchange module.
 
    .EXAMPLE
    Add a single mailbox to a single distribution group
 
    Add-DistributionMember -Mailbox JohnD@company.com -DistributionGroup "All Employees"
 
    .EXAMPLE
    Allows shortening the command or adding multiple mailboxes with a shared name to a Distribuiton Group
 
    Add-DistributionMember -Mailbox *@company.com -DistributionGroup "All Emp*"
 
    .EXAMPLE
    Add a single mailbox to multiple Distribution Groups.
 
    Add-DistributionMember -Mailbox JohnD@company.com -DistributionGroup "All Employees,Worker Bees"
    #>


    [CmdletBinding()]

    Param (
        [Parameter(Mandatory = $true)]$Mailbox,
        [Parameter(Mandatory = $true)]$DistribuitonGroup
    )

    Get-Mailbox -identity $Mailbox | add-distributiongroupmember -identity $DistribuitonGroup
}

Function Add-LocalAdmin {

    <#
    .SYNOPSIS
    -Taylor Lee
    Modified 05172019
 
    .DESCRIPTION
    This function adds a local admin to the computer or server it is run from.
 
    .NOTES
    Azure AD Joined machines will require the user to first login to a computer with their domain account before adding their domain account as a local admin.
    The user logging in registers their SID so that the command is succesful.
 
    .EXAMPLE
    Adds specified domain user to the local administrators group
 
    Add-LocalAdmin -user domain\user
    #>


    [CmdletBinding()]

    Param (
        [Parameter(Mandatory = $true)]$user
    )

    Net Localgroup Administrators $user /add

}

function Clear-Arp {
    <#
    .SYNOPSIS
    -Taylor Lee
    Modified 05292019
 
    .DESCRIPTION
    Clears the local arp table
    #>

    netsh.exe interface ip delete arpcache
}

Function Connect-Office365 {

    <#
    .SYNOPSIS
    -Taylor Lee
    Modified 05172019
 
    .DESCRIPTION
    Connect to all Office 365 Modules or just those chosen using the provided parameters
 
    .Example
    Connect-Office365 -acctName name@bigcompany.com -domainHost bigcompany -all
 
    Connects to all included office 365 modules for this Function
 
    .Example
    Connect-Office365 -acctName name@bigcompany.com -skype
 
    Connects to skype and includes it mandatory parameters
 
    .Example
    Connect-Office365 -domainhost bigcompany -SharepointOnline
 
    Connects to skype and includes it mandatory parameters
 
    .Example
    Connect-Office365 -AzureAD
 
    Connects to a specific module using the available AzureAD parameter
 
    .Example
    Connect-Office365 -AzureAD -Teams
 
    Connects to multiple specified modules
 
    .Notes
    SECURITY AND COMPLIANCE remove from all switch due to breaking behaviour.
 
    #Sharepoint Online Module
    The SharePoint Online Management Shell is a Windows PowerShell module that you can use to manage SharePoint Online users, sites, and site collections.
    Sharepoint Online Module https://www.microsoft.com/en-us/download/details.aspx?id=35588
 
    #Azure AD Module
    Windows Azure AD tenant-based administrative tasks such as user management, domain management and for configuring single sign-on
    Install-Module AzureAD
 
    #Exchange Online Module
    Exchange Online PowerShell allows you to manage your Exchange Online settings from the command line.
    Download the Exchange Online Module from the Hybrid section of Office 365 Exchange Admin Center
 
    #Security and Compliance Module
    Office 365 Security & Compliance Center PowerShell allows you to manage your Office 365 Security & Compliance Center settings from the command line.
    Download the Exchange Online Module from the Hybrid section of Office 365 Exchange Admin Center
 
    #Skype For Business Module
    Skype For Business Module allows managing Skype for Business settings from the Command Line.
    Download and install Skype for Business Module https://www.microsoft.com/en-us/download/details.aspx?id=39366
    If bug still exists, Visual C++ 2017 x64 14.10.25008 is needed to work with this module.
 
    #Microsoft Teams Module
    Microsoft Teams Module Module allows managing Microsoft Teams settings from the Command Line.
    Install-module MicrosoftTeams
 
    #Azure AZ Module
    Azure Az Module Module allows managing Azure settings, subscriptions, VM, Resource groups, and more from the Command Line.
    Replaces Azure RM
    Install-Module -Name Az
    #>


    [CmdletBinding(SupportsShouldProcess)]

    Param (
        [Parameter(Mandatory = $true, ParameterSetName = "All")][Parameter(Mandatory = $true, ParameterSetName = "Skype")]$AcctName,
        [Parameter(Mandatory = $true, ParameterSetName = "All")][Parameter(Mandatory = $true, ParameterSetName = "Sharepoint")]$DomainHost,
        [Parameter(Mandatory = $true, ParameterSetName = "All")][Switch] $All,
        [Parameter(Mandatory = $true, ParameterSetName = "AzureAD")][Switch] $AzureAD,
        [Parameter(Mandatory = $true, ParameterSetName = "Sharepoint")][Switch] $SharepointOnline,
        [Parameter(Mandatory = $true, ParameterSetName = "ExchangeOnline")][Switch] $ExchangeOnline,
        [Parameter(Mandatory = $true, ParameterSetName = "SecurityandCompliance")][Switch] $SecurityandCompliance,
        [Parameter(Mandatory = $true, ParameterSetName = "Skype")][Switch] $Skype,
        [Parameter(Mandatory = $true, ParameterSetName = "Teams")][Switch] $Teams,
        [Parameter(Mandatory = $true, ParameterSetName = "Az")][Switch] $Az
    )

    #Importing Exchange Online Module
    $CreateEXOPSSession = (Get-ChildItem -Path $env:userprofile -Filter CreateExoPSSession.ps1 -Recurse -ErrorAction SilentlyContinue -Force | Select-Object -Last 1).DirectoryName
    . "$CreateEXOPSSession\CreateExoPSSession.ps1"

    if ($SharepointOnline) {
        #Sharepoint Online Module
        Import-Module Microsoft.Online.SharePoint.PowerShell -DisableNameChecking
        Write-Host "Connecting to SharePoint Online" -backgroundcolor black -foregroundcolor green
        Connect-SPOService -Url https://$DomainHost-admin.sharepoint.com
    }

    if ($AzureAD) {
        #Azure AD Module
        Write-Host "Connecting to other Azure AD Services" -backgroundcolor black -foregroundcolor green
        Connect-AzureAD
    }

    if ($ExchangeOnline) {
        #Exchange Online Module
        Write-Host "Connecting to Exchange Online Services" -backgroundcolor black -foregroundcolor green
        Connect-EXOPSSession
    }

    if ($SecurityandCompliance) {
        #Security and Compliance Module
        Write-Host "Connecting to Exchange Online Protection and Security (aka Security and Compliance)" -backgroundcolor black -foregroundcolor green
        Connect-ippssession
    }

    if ($Skype) {
        #Skype For Business Module
        Import-Module SkypeOnlineConnector
        Write-Host "Connecting to Skype for Business Online" -backgroundcolor black -foregroundcolor green
        $sfboSession = New-CsOnlineSession -UserName $AcctName
        Import-PSSession $sfboSession
    }

    if ($Teams) {
        #Microsoft Teams Module
        Write-Host "Connecting to Microsoft Teams" -backgroundcolor black -foregroundcolor green
        Connect-MicrosoftTeams

        $SkypeRequired = Read-Host "Did you import the additionaly required skype module? Yes or No"

        if ($SkypeRequired -eq 'No') {
            #Skype For Business Module
            Import-Module SkypeOnlineConnector
            Write-Host "Connecting to Skype for Business Online" -backgroundcolor black -foregroundcolor green
            $sfboSession = New-CsOnlineSession -UserName $AcctName
            Import-PSSession $sfboSession

        }
    }

    if ($Az) {
        #Azure Az Module
        Write-Host "Connecting to Azure Az Module" -backgroundcolor black -foregroundcolor green
        Connect-AzAccount
    }

    if ($All) {
        #Sharepoint Online Module
        Import-Module Microsoft.Online.SharePoint.PowerShell -DisableNameChecking
        Write-Host "Connecting to SharePoint Online" -backgroundcolor black -foregroundcolor green
        Connect-SPOService -Url https://$DomainHost-admin.sharepoint.com

        #Azure AD Module
        Write-Host "Connecting to other Azure AD Services" -backgroundcolor black -foregroundcolor green
        Connect-AzureAD

        #Exchange Online Module
        Write-Host "Connecting to Exchange Online Services" -backgroundcolor black -foregroundcolor green
        Connect-EXOPSSession

        #Skype For Business Module
        Import-Module SkypeOnlineConnector
        Write-Host "Connecting to Skype for Business Online" -backgroundcolor black -foregroundcolor green
        $sfboSession = New-CsOnlineSession -UserName $AcctName
        Import-PSSession $sfboSession

        #Microsoft Teams Module
        Write-Host "Connecting to Microsoft Teams" -backgroundcolor black -foregroundcolor green
        Connect-MicrosoftTeams

        #Azure Az Module
        Write-Host "Connecting to Azure Az Module" -backgroundcolor black -foregroundcolor green
        Connect-AzAccount
    }

    Write-Host "Going to import modules with verbose switch so all commands are available" -backgroundcolor black -foregroundcolor green
    Pause
    Get-Module | Import-Module -verbose
    Clear-Host
}

Function Disable-Account {

    <#
    -Taylor Lee
    Modified 05172019
 
    .DESCRIPTION
    Disables a specified Active Directory Account
 
    .NOTES
    Requires the Active Directory Module
 
    .EXAMPLE
    Use the Samaccountname of the account being disabled
 
    Disable-ADAccount -Account JohnDoe
 
    .EXAMPLE
    Use the DistinguishedName of the account being disabled
 
    Disable-ADAccount -Account "CN=John Doe,OU=Finance,OU=UserAccounts,DC=FABRIKAM,DC=COM"
 
    .EXAMPLE
    -Use the UserPrincipalName of the account being disabled
 
    Disable-ADAccount -Account JohnD@Company.com
    #>


    [CmdletBinding()]

    Param (
        [Parameter(Mandatory = $true)]$Account
    )

    Import-Module ActiveDirectory

    Disable-ADAccount -Identity $Account -Confirm
}

Function Disable-ShakeToMinimize {

    <#
    .Synopsis
    -Taylor Lee
    Modified 05172019
 
    .Description
    This Function disables the annoying shake to minimize Windows feature
    #>


    [CmdletBinding()]
    param (
    )

    reg add "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /f /v "DisallowShaking" /t reg_dword /d 1

}

Function Disable-Sleep {

    <#
    .Synopsis
    -Taylor Lee
    Modified 05172019
 
    .DESCRIPTION
    This command disables hibernate and sleep
    #>


    [CmdletBinding()]
    param (
    )

    Write-Host Disabling Standby -foregroundcolor green
    powercfg.exe -change -standby-timeout-ac 0
    powercfg.exe -change -standby-timeout-dc 0
    powercfg.exe -change -hibernate-timeout-ac 0
    powercfg.exe -change -hibernate-timeout-dc 0
    powercfg -h off

}

Function Disable-UAC {

    <#
    .Synopsis
    -Taylor Lee
    Modified 05172019
 
    .Description
    This Function disable UAC and removes the Consent Prompt Behaviour.
    #>


    [CmdletBinding()]
    param (
    )

    reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /f /v "ConsentPromptBehaviorAdmin" /t reg_dword /d 0
    reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /f /v "EnableLUA" /t reg_dword /d 0

}

Function Disable-UACPrompt {

    <#
    .Synopsis
    -Taylor Lee
    Modified 05172019
 
    .Description
    This Function disables UAC Consent Prompting for local Administrators.
    #>


    [CmdletBinding()]
    param (
    )

    reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /f /v "ConsentPromptBehaviorAdmin" /t reg_dword /d 0

}

Function Disable-Updates {

    <#
    .Synopsis
    -Taylor Lee
    Modified 05172019
 
    .DESCRIPTION
    This command disable automatic updates
    #>


    [CmdletBinding()]
    param (
    )

    reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update" /v AUOptions /t REG_DWORD /d 1 /f
    net stop wuauserv
    net start wuauserv

}

Function Enable-Account {

    <#
    .SYNOPSIS
    -Taylor Lee
    Modified 05172019
 
    .DESCRIPTION
    Enables a specified Active Directory Account
 
    .NOTES
    Requires the Active Directory Module
 
    .EXAMPLE
    Use the Samaccountname of the account being disabled
 
     Enable-ADAccount -Account JohnD
 
    .EXAMPLE
    Use the DistinguishedName of the account being disabled
 
    Enable-ADAccount -Account "CN=John Doe,OU=Finance,OU=UserAccounts,DC=FABRIKAM,DC=COM"
 
    .EXAMPLE
    Use the UserPrincipalName of the account being disabled
 
    Enable-ADAccount -Account PJohnD@Company.com
    #>


    [CmdletBinding()]

    Param (
        [Parameter(Mandatory = $true)]$Account
    )

    Import-Module ActiveDirectory

    Enable-ADAccount -Identity $Account -Confirm
}

Function Enable-Remoting {
    <#
    .Synopsis
    -Taylor Lee
    Modified 05172019
 
    .Description
    This Command will enable PowerShell Remoting on a remote PC.
 
    .NOTES
    This Function requires psexec. If you do not, download it with the sysinternals suite. Add psexec to one of your enviroment variable paths.
 
    .EXAMPLE
    This will enable remoting and then prompt for credentials
 
    Enable-PSRemoting -computer PCName -username domain\username
    #>


    [CmdletBinding()]

    Param (
        [Parameter(Position = 0, Mandatory = $true)]$Computer,
        [Parameter(Position = 1, Mandatory = $false)]$Username,
        [Parameter(Position = 2, Mandatory = $false)][SecureString]$Password
    )

    #Enabling PSRemoting
    psexec \\$Computer -s winrm.cmd quickconfig -q
    psexec \\$Computer -u $Username -p $Password powershell.exe cmd /c "enable-psremoting -force"


    #Testing that PSRemoting is now enabled.
    Write-Host "If an error is presented after this point PSRemoting wasn't enabled"       -Foregroundcolor Yellow
    Test-WsMan $Computer
}

Function Enable-UAC {

    <#
    .Synopsis
    -Taylor Lee
    Modified 05172019
 
    .Description
    This Function enables UAC and sets the Consent Prompt Behaviour.
    #>


    [CmdletBinding()]
    param (
    )
    reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /f /v "ConsentPromptBehaviorAdmin" /t reg_dword /d 2
    reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /f /v "EnableLUA" /t reg_dword /d 1

}

Function Find-ComputersFiles {

    <#
    .SYNOPSIS
    -Taylor Lee
    Modified 05172019
 
    .DESCRIPTION
    Discover queried files meeting a specific search parameter and output the findings to a spreadsheet.
 
    .EXAMPLE
    Searches computers listed in the text file for pst files and outputs the findings to a spreadsheet.
    (Computers should be line delimited)
 
    find-computersfiles -computers C:\computers.txt -csvout c:\results.csv -include *.pst
 
    .EXAMPLE
    Performs the same function as the first example, except it only searches the specified path and it's subfolders.
 
    find-computersfiles -computers C:\computers.txt -csvout c:\results.csv -include *.pst -path "c$\users\username\appdata\local"
    #>


    [CmdletBinding(SupportsShouldProcess)]
    Param (
        #Variable containing computers being queried
        [Parameter(Position = 0, Mandatory = $true)]$computers,
        #Variable containing output path for csv file
        [Parameter(Position = 1, Mandatory = $true)]$csvout,
        #Variable specifying search parameter
        [Parameter(Position = 2, Mandatory = $true)]$include,
        #Variable specifying search parameter
        [Parameter(Position = 3)]$Path = "c$"
    )

    #Supress Errors
    $ErrorActionPreference = 'SilentlyContinue'

    #Runs to find all files that match the query on all included computers and outputs the results to a CSV
    Get-Content $computers |
        ForEach-Object {Get-ChildItem "\\$_\$path" -Include $include -Recurse} |
        Select-Object Name, Directory, Length, LastAccessTime, LastWriteTime, CreationTime |
        Export-Csv $csvout -Append -NoTypeInformation

    #Restores default error action of show
    $ErrorActionPreference = 'Continue'
}

Function Get-ADInfo {

    <#
    .Synopsis
    -Taylor Lee
    Modified 05172019
 
    .Description
    This Function will return domain info. Requires the Active Directory Module.
 
    .NOTES
    Requires the Active Directory Module
    #>


    [CmdletBinding()]
    param (
    )

    Import-Module ActiveDirectory

    Get-ADDomain |
    Select-Object Name, Forest, ChildDomains, DistinguishedName, DNSRoot, DomainMode, ReplicaDirectoryServers, InfrastructureMaster, RIDMaster, PDCEmulator |
    Format-List

    Get-ADForest |
    Select-Object DomainNamingMaster, SchemaMaster |
    Format-List

}

Function Get-Applications {

    <#
    .SYNOPSIS
    -Taylor Lee
    Modified 05172019
 
    .DESCRIPTION
    List installed Applications
    #>


    [CmdletBinding()]
    param (
    )

    Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* |
    Select-Object DisplayName, DisplayVersion, Publisher, InstallDate |
    Sort-Object DisplayName

}

Function Get-CloseEncounters {
    [console]::beep(900, 400);
    [console]::beep(1000, 400);
    [console]::beep(800, 400);
    [console]::beep(400, 400);
    [console]::beep(600, 1600);
    [console]::beep(900, 350);
    [console]::beep(1000, 350);
    [console]::beep(800, 350);
    [console]::beep(400, 350);
    [console]::beep(600, 1400);
    [console]::beep(900, 300);
    [console]::beep(1000, 300);
    [console]::beep(800, 300);
    [console]::beep(400, 300);
    [console]::beep(600, 1200);
    [System.Threading.Thread]::Sleep(400);
    [console]::beep(900, 400);
    [console]::beep(1000, 400);
    [console]::beep(800, 400);
    [console]::beep(400, 400);
    [console]::beep(600, 1600);
}

Function Get-DCLockoutEvents2 {

    <#
    .SYNOPSIS
    -Taylor Lee
    Modified 05172019
 
    .DESCRIPTION
    Parse Logs 4740 and 4776 on the PDCEmulator for workstations causing a lockout. Null lockout location events are filtered. Best if run shortly after a lockout.
 
    .EXAMPLE
    Get-DCLockoutEvents2 -identity Joe
 
    .Notes
    Requires The Active Directory Module
    #>


    [CmdletBinding(SupportsShouldProcess)]
    Param(
        [Parameter(Mandatory = $True)]
        [String]$Identity
    )

    #Getting the PDCEmulator
    $DomainControllers = Get-ADDomainController -Filter *
    $PDCEmulator = ($DomainControllers | Where-Object {$_.OperationMasterRoles -contains "PDCEmulator"})

    #Parsing Event Log 4740
    Write-Host "Querying event id 4740 on $PDCEmulator." -Backgroundcolor Black -ForegroundColor Yellow
    $PDCEmulator | Foreach-Object {
        Get-WinEvent -ComputerName $_ -FilterHashtable @{LogName = 'Security'; Id = 4740} |
            where-object {($_.Properties[1].Value -notlike $null -and $_.Properties[0].Value -eq $Identity)} |
            Select-Object -Property @(
            @{Label = 'User'; Expression = {$_.Properties[0].Value}}
            @{Label = 'LockedOutLocation'; Expression = {$_.Properties[1].Value}}
            @{Label = 'LockedOutTimeStamp'; Expression = {$_.TimeCreated}}
            @{Label = 'DomainController'; Expression = {$_.MachineName}}
            @{Label = 'EventId'; Expression = {$_.Id}}
        ) |
            Format-Table
    }#endforeach

    #Parsing Event Log 4776
    Write-Host "Querying event id 4776 on $PDCEmulator; this will take awhile. Use ctrl+c to end at any time." -Backgroundcolor Black -ForegroundColor Yellow
    $PDCEmulator | Foreach-Object {
        Get-WinEvent -ComputerName $_ -FilterHashtable @{LogName = 'Security'; Id = 4776} |
            where-object {($_.Properties[2].Value -notlike $null -and $_.Properties[1].Value -eq $Identity -and $_.KeywordsDisplayNames -contains "Audit Failure")} |
            Select-Object -Property @(
            @{Label = 'User'; Expression = {$_.Properties[1].Value}}
            @{Label = 'BadPasswordLocation'; Expression = {$_.Properties[2].Value}}
            @{Label = 'BadPasswordAttemptTime'; Expression = {$_.TimeCreated}}
            @{Label = 'DomainController'; Expression = {$_.MachineName}}
            @{Label = 'EventID'; Expression = {$_.ID}}
        ) |
            Format-Table
    }#endforeach
}#endfunction

Function Get-EndpointReport {

    <#
    .SYNOPSIS
    -Taylor Lee
    Modified 05172019
 
    .DESCRIPTION
    Create a CSV report of Active Directory Endpoints
 
    .NOTES
    Requires the Active Directory Module
 
    .Example
    Be sure to specify a filename and extension for the report.
 
    Get-EndpointReport -path C:\UserReport.csv
    #>


    [CmdletBinding(SupportsShouldProcess)]

    Param (
        [Parameter(Mandatory = $true)]$Path
    )

    Import-Module ActiveDirectory

    Get-ADComputer -Filter {(Enabled -eq $true)} -properties * |
        select-object name, OperatingSystem, whenCreated, LastLogonDate |
        Export-CSV $Path -NoTypeInformation

}

Function Get-Excuse {

    <#
    .Synopsis
    -Taylor Lee
    Modified 05172019
 
    .DESCRIPTION
    Are you out of excuses. Let powershell help you
    #>


    [CmdletBinding(SupportsShouldProcess)]

    $ex = (Invoke-WebRequest http://pages.cs.wisc.edu/~ballard/bofh/excuses -OutVariable excuses).content.split([Environment]::NewLine)[(get-random $excuses.content.split([Environment]::NewLine).count)]

    Write-Host " "
    write-host "$ex" -Foregroundcolor Green
    Write-Host " "

    Add-Type -AssemblyName System.Speech
    $SpeechSynth = New-Object System.Speech.Synthesis.SpeechSynthesizer
    $SpeechSynth.Speak("$ex")
}

Function Get-FileOwner {

    <#
    .Synopsis
    -Taylor Lee
    Modified 05172019
 
    .Description
    This Function produces a CSV listing file owners within a given path
 
    .Example
    Specify the parent folder from which all subfolders are queried and where the report should be saved.
 
     Get-FileOwner -Path c:\users -Report c:\FileOwners.csv
    #>


    [CmdletBinding(SupportsShouldProcess)]

    PARAM (
        [Parameter(Mandatory = $true)]$Path,
        [Parameter(Mandatory = $true)]$Report
    )

    $LastWrite = @{
        Name       = 'Last Write Time'
        Expression = { $_.LastWriteTime.ToString('u') }
    }
    $Owner = @{
        Name       = 'File Owner'
        Expression = { (Get-Acl $_.FullName).Owner }
    }
    $HostName = @{
        Name       = 'Host Name'
        Expression = { $env:COMPUTERNAME }
    }

    Get-ChildItem -Recurse -Path $Path |
    Select-Object $HostName, $Owner, Name, Directory, $LastWrite, Length |
    Export-Csv -NoTypeInformation $Report

}

Function Get-FolderSize {

    <#
    .SYNOPSIS
    -Taylor Lee
    Modified 05172019
 
    .DESCRIPTION
    Quckly Finds the size of a path
 
    .EXAMPLE
    Finds the size of the C:\users folder in MegaBytes
 
    Get-Foldersize -Folder c:\users\ -ByteSize MB
 
    .EXAMPLE
    Finds the size of the C:\users folder in GigaBytes
 
    Get-Foldersize -Folder c:\users\ -ByteSize GB
 
    .EXAMPLE
    Finds the size of the C:\users folder in MegaBytes
 
    Get-Foldersize -Folder c:\users\ -ByteSize TB
    #>


    [CmdletBinding()]
    Param (
        [Parameter(Position = 0, Mandatory = $true)]$Folder,
        [Parameter(Position = 1)]$ByteSize
    )

    if ($ByteSize -eq 'MB') {
        "{0:N2} MB" -f ((Get-ChildItem $Folder -Recurse | Measure-Object -Property Length -Sum -ErrorAction Stop).Sum / 1MB)
    }
    elseif ($ByteSize -eq 'GB') {
        "{0:N2} GB" -f ((Get-ChildItem $Folder -Recurse | Measure-Object -Property Length -Sum -ErrorAction Stop).Sum / 1GB)
    }
    elseif ($ByteSize -eq 'TB') {
        "{0:N2} TB" -f ((Get-ChildItem $Folder -Recurse | Measure-Object -Property Length -Sum -ErrorAction Stop).Sum / 1TB)
    }
    else {
        "{0:N2} MB" -f ((Get-ChildItem $Folder -Recurse | Measure-Object -Property Length -Sum -ErrorAction Stop).Sum / 1MB)
    }
}

Function Get-GPORegistry {
    <#
    .SYNOPSIS
    -Taylor Lee
    Modified 05172019
 
    .DESCRIPTION
    Get registry keys that are changed by enabled Group Policy Objects
 
    .NOTES
    Parent Keys to use for the $key variable
 
    "hkcu\appevents"
    "hkcu\console"
    "hkcu\control panel"
    "hkcu\enviroment"
    "hkcu\eudc"
    "hkcu\keyboard layout"
    "hkcu\microsoft"
    "hkcu\network"
    "hkcu\printers"
    "hkcu\remote"
    "hkcu\run"
    "hkcu\software"
    "hkcu\system"
    "hkcu\uninstall"
    "hklm\hardware"
    "hklm\sam"
    "hklm\security"
    "hklm\software"
    "hklm\system"
 
    .EXAMPLE
    Gets Software Keys for a given Group Policy
 
    Get-GPORegistry -gponame "office 365" -key "hklm\software"
    #>


    [CmdletBinding(SupportsShouldProcess)]
    param(
        [Parameter(Mandatory = $true)]
        [string]$GPOName,
        [Parameter(Mandatory = $true)]
        [string]$Key

    )
    $current = Get-GPRegistryValue -Name $gpoName -Key $key
    foreach ($item in $current) {
        if ($item.ValueName -ne $null) {
            [array]$returnVal += $item
        }
        else {
            Get-GPORegistry -Key $item.fullkeypath -gpoName $gpoName
        }
    }
    return $returnVal
}

Function Get-ImperialMarch {
    [console]::beep(440, 500)
    [console]::beep(440, 500)
    [console]::beep(440, 500)
    [console]::beep(349, 350)
    [console]::beep(523, 150)

    [console]::beep(440, 500)
    [console]::beep(349, 350)
    [console]::beep(523, 150)
    [console]::beep(440, 1000)

    [console]::beep(659, 500)
    [console]::beep(659, 500)
    [console]::beep(659, 500)
    [console]::beep(698, 350)
    [console]::beep(523, 150)

    [console]::beep(415, 500)
    [console]::beep(349, 350)
    [console]::beep(523, 150)
    [console]::beep(440, 1000)

    [console]::beep(880, 500)
    [console]::beep(440, 350)
    [console]::beep(440, 150)
    [console]::beep(880, 500)
    [console]::beep(830, 250)
    [console]::beep(784, 250)

    [console]::beep(740, 125)
    [console]::beep(698, 125)
    [console]::beep(740, 250)

    [console]::beep(455, 250)
    [console]::beep(622, 500)
    [console]::beep(587, 250)
    [console]::beep(554, 250)

    [console]::beep(523, 125)
    [console]::beep(466, 125)
    [console]::beep(523, 250)

    [console]::beep(349, 125)
    [console]::beep(415, 500)
    [console]::beep(349, 375)
    [console]::beep(440, 125)

    [console]::beep(523, 500)
    [console]::beep(440, 375)
    [console]::beep(523, 125)
    [console]::beep(659, 1000)

    [console]::beep(880, 500)
    [console]::beep(440, 350)
    [console]::beep(440, 150)
    [console]::beep(880, 500)
    [console]::beep(830, 250)
    [console]::beep(784, 250)

    [console]::beep(740, 125)
    [console]::beep(698, 125)
    [console]::beep(740, 250)

    [console]::beep(455, 250)
    [console]::beep(622, 500)
    [console]::beep(587, 250)
    [console]::beep(554, 250)

    [console]::beep(523, 125)
    [console]::beep(466, 125)
    [console]::beep(523, 250)

    [console]::beep(349, 250)
    [console]::beep(415, 500)
    [console]::beep(349, 375)
    [console]::beep(523, 125)

    [console]::beep(440, 500)
    [console]::beep(349, 375)
    [console]::beep(261, 125)
    [console]::beep(440, 1000)
}

Function Get-Info {

    <#
    .Synopsis
    -Taylor Lee
    Modified 05172019
 
    .Description
    A Functions list for the Powershell Profile
    #>


    Write-Host " -------------------------------------------------------------------"                      -Foregroundcolor Green
    Write-Host " | Some functions require additional Powershell Modules |"                      -Foregroundcolor Green
    Write-Host " | Use Get-Help <Command> -full to view any prerequisites |"                      -Foregroundcolor Green
    Write-Host " | Make sure you are using the latest version of powershell |"                      -Foregroundcolor Green
    Write-Host " -------------------------------------------------------------------"                      -Foregroundcolor Green
    pause
    Write-Host "Active Directoy Commands"                                                                  -Foregroundcolor green
    Write-Host "Get-ADInfo ..Gets info on local domain"                                    -Foregroundcolor cyan
    Write-Host "Get-DCLockoutEvents2 ..Gets endpoints causing user lockouts"                         -ForegroundColor cyan
    Write-Host "Get-EndpointReport ..Gets a Report of AD Endpoints"                                -Foregroundcolor cyan
    Write-Host "Get-LockedAccounts ..Gets locked AD accounts"                                      -Foregroundcolor cyan
    Write-Host "Get-PasswordExpired ..Gets AD accounts with Expired Passwords"                      -Foregroundcolor cyan
    Write-Host "Get-UserReport ..Gets a Report of AD Users"                                    -Foregroundcolor cyan
    Write-Host "Set-Password ..Sets an AD Password"                                          -Foregroundcolor cyan
    Write-Host "Unlock-Account ..Unlocks an AD account"                                        -Foregroundcolor cyan
    Write-Host "Unlock-AllAccounts ..Unlocks all AD accounts"                                      -Foregroundcolor cyan
    Write-Host " "
    Write-Host "Custom Aliases"                                                                            -Foregroundcolor green
    Write-Host "scm ..Alias for Show-Command"                                       -Foregroundcolor cyan
    Write-Host "gel ..Alias for Get-Location"                                       -Foregroundcolor cyan
    Write-Host " "
    Write-Host "Custom Modules"                                                                            -Foregroundcolor green
    Write-Host "Admin Toolbox ..Module with many usefulle tools"                              -ForegroundColor cyan
    Write-Host "FFTools ..Module for FFMpeg"                                            -Foregroundcolor cyan
    Write-Host "PCSetup ..Module for PC Setup"                                          -Foregroundcolor cyan
    Write-Host " "
    Write-Host "Endpoint Management Commands"                                                              -Foregroundcolor green
    Write-Host "Add-LocalAdmin ..Adds a local admin to the endpoint"                           -Foregroundcolor cyan
    Write-Host "Disable-ShakeToMinimize ..Disables Annoying Shake to Minimize"                          -Foregroundcolor cyan
    Write-Host "Disable-Sleep ..Disables Hibernate and Sleep"                                 -Foregroundcolor cyan
    Write-Host "Disable-UAC ..Disables UAC"                                                 -Foregroundcolor cyan
    Write-Host "Disable-UACPrompt ..Disabless UAC Prompting for Admins but not UAC elevation"     -Foregroundcolor cyan
    Write-Host "Enable-Remoting ..Enables PSRemoting"                                           -Foregroundcolor cyan
    Write-Host "Enable-UAC ..Enables UAC"                                                  -Foregroundcolor cyan
    Write-Host "Get-Applications ..Gets a list of installed Applications"                        -Foregroundcolor cyan
    Write-Host "Get-Management ..Gets Computer Management for another endpoint"                -Foregroundcolor cyan
    Write-Host "Get-PCInfo ..Gets info on targeted PC"                                     -Foregroundcolor cyan
    Write-Host "Remove-AppName ..Remove application matching specified name"                   -Foregroundcolor cyan
    Write-Host "Remove-AppNameLike ..Remove application like specified name"                       -Foregroundcolor cyan
    Write-Host "Reset-NetworkStack ..Reset TCP/IP and Winsock"                                     -Foregroundcolor cyan
    Write-Host "Reset-NetworkAdapter ..Reset Network Adapters"                                       -Foregroundcolor cyan
    Write-Host "Restart-Endpoint ..Restart the endpoint after X provided hours"                  -Foregroundcolor cyan
    Write-Host " "
    Write-Host "Exchange Commands"                                                                         -Foregroundcolor green
    Write-Host "Add-DistributionMember ..Adds a mailbox to a Distibution Group"                        -Foregroundcolor cyan
    Write-Host "Get-MailLog ..Gets a csv of mail logs"                                      -Foregroundcolor cyan
    Write-Host "Get-UserDisabledMailboxes ..Gets mailboxes associated with disabled ad accounts"          -Foregroundcolor cyan
    Write-Host "Get-VirtualDirectories ..Gets IIS virtual directories for Exchange"                    -ForegroundColor cyan
    Write-Host " "
    Write-Host "File Commands"                                                                             -Foregroundcolor green
    Write-Host "Get-FileOwner ..Gets CSV of file owners for a path"                           -Foregroundcolor cyan
    Write-Host "Get-FolderSize ..Gets FolderSize of a single folder quickly"                   -Foregroundcolor cyan
    Write-Host "Find-ComputersFiles ..Finds queried files across 1 or more Computers"               -ForegroundColor cyan
    Write-Host "Remove-All ..Removes many files quickly to free up space"                  -Foregroundcolor cyan
    Write-host "Remove-DisabledADProfiles ..Removes local profiles of disabled AD users"                  -Foregroundcolor cyan
    Write-Host "Remove-OlderThan ..Removes folders and files older than"                         -Foregroundcolor cyan
    Write-Host "Remove-Path ..Removes specified files and folders"                          -Foregroundcolor cyan
    Write-Host " "
    Write-Host "Fun"                                                                                       -Foregroundcolor green
    Write-Host "Get-CloseEncounters ..Get Close Encounters"                                         -Foregroundcolor cyan
    Write-Host "Get-Excuse ..Gets a joke"                                                  -Foregroundcolor cyan
    Write-Host "Get-ImperialMarch ..Get Imperial March"                                           -Foregroundcolor cyan
    Write-Host "Get-MissionImpossible ..Get Mission Impossible"                                       -Foregroundcolor cyan
    Write-Host "Get-Mario ..Get Mario"                                                    -Foregroundcolor cyan
    Write-Host "Get-Tetris ..Get Tetris"                                                   -Foregroundcolor cyan
    Write-Host "Get-Weather ..Get The Weather"                                              -Foregroundcolor cyan
    Write-Host " "
    Write-Host "Networking Commands"                                                                       -Foregroundcolor green
    Write-Host "Clear-arp ..Clears the local arp table"                                   -Foregroundcolor cyan
    Write-Host "Clear-DNSClientCache ..Clears the DNS Cache"                                         -Foregroundcolor cyan
    Write-Host "Get-DNSClientCache ..Gets the DNS Cache"                                           -Foregroundcolor cyan
    Write-Host "Get-NetIPConfiguration ..Gets Network Interface Config"                                -Foregroundcolor cyan
    Write-Host "Get-NetworkStatistics ..Gets active connections and associated processes"             -Foregroundcolor cyan
    Write-Host "Get-PublicIP ..Gets Public Whois Info for specified address"                 -ForegroundColor cyan
    Write-Host "Invoke-PSNmap ..Invoke nmap scan on targets"                                  -ForegroundColor cyan
    Write-Host "Invoke-PSipcalc ..Invoke CIDR IP Calculator"                                    -ForegroundColor cyan
    Write-Host "Resolve-DNSName ..Resolves DNS and filter for record type"                      -Foregroundcolor cyan
    Write-Host "Test-Netconnection ..Tests Ping, Traceroute, Route Diagnosing, and Port Testing"   -Foregroundcolor cyan
    Write-Host " "
    Write-Host "Office 365 Commands"                                                                       -Foregroundcolor green
    Write-Host "Connect-Office365 ..Connects to Office 365 Module"                                -Foregroundcolor cyan
    Write-Host "Start-AzureSync ..Starts an Azure AD and Local AD Sync"                         -Foregroundcolor cyan
    Write-Host " "
    Write-Host "Print/er Management Commands"                                                              -Foregroundcolor green
    Write-Host "Get-Printers ..Gets printer information"                                     -Foregroundcolor cyan
    Write-Host "Get-PrintManagement ..Gets Print Management"                                        -Foregroundcolor cyan
    Write-Host "Remove-PrintQueue ..Removes all print queues"                                     -Foregroundcolor cyan
}

Function get-intro {
    Clear-Host
    Write-host "
        _______ __ __ _______ __ __
       | _ .--| .--------|__.-----. | .-----.-----| | |--.-----.--.--.
       |. 1 | _ | | | | |.| | | _ | _ | | _ | _ |_ _|
       |. _ |_____|__|__|__|__|__|__| `-|. |-|_____|_____|__|_____|_____|__.__|
       |: | | |: |
       |::.|:. | |::.|
        `--- ---' `---'
      "
 -Foregroundcolor Green

    Write-Host " --------------------------------------------------------------------"      -Foregroundcolor Green
    Write-Host " > Use Get-Info to see a list of Commands <"      -Foregroundcolor Green
    Write-Host " > Use Get-Intro to Clear-Host and return here <"      -Foregroundcolor Green
    Write-Host " --------------------------------------------------------------------"      -Foregroundcolor Green

    Write-host " "
}

Function get-intro2 {
    Write-host "
        _______ __ __ _______ __ __
       | _ .--| .--------|__.-----. | .-----.-----| | |--.-----.--.--.
       |. 1 | _ | | | | |.| | | _ | _ | | _ | _ |_ _|
       |. _ |_____|__|__|__|__|__|__| `-|. |-|_____|_____|__|_____|_____|__.__|
       |: | | |: |
       |::.|:. | |::.|
        `--- ---' `---'
      "
 -Foregroundcolor Green

    Write-Host " --------------------------------------------------------------------"      -Foregroundcolor Green
    Write-Host " > Use Get-Info to see a list of Commands <"      -Foregroundcolor Green
    Write-Host " > Use Get-Intro to Clear-Host and return here <"      -Foregroundcolor Green
    Write-Host " --------------------------------------------------------------------"      -Foregroundcolor Green

    Write-host " "
}

Function Get-LockedAccounts {

    <#
    .Synopsis
    -Taylor Lee
    Modified 05172019
 
    .Description
    Return a list of Locked Active Directory Accounts
 
    .Notes
    Requires the Active Directory Module
    #>


        Import-Module ActiveDirectory

        Search-ADAccount -Lockedout |
        Select-Object Name, SamAccountName, UserPrincipalName |
        Sort-Object Name |
        Format-Table -AutoSize
    }

Function Get-MailLog {

    <#
    .SYNOPSIS
    -Taylor Lee
    Modified 05172019
 
    .DESCRIPTION
    Creates a csv file containg logs of mail in a given time frame.
 
    .NOTES
    Requires the Microsoft Exchange module.
 
    .EXAMPLE
    Specify the date range, report path, and amount of records to return.
 
    Get-MailLog -StartDate 05/14/2017 -EndDate 05/14/2018 -ExportPath C:\MailLog.CSV
 
    #>


    [CmdletBinding(SupportsShouldProcess)]

    Param (
        [Parameter(Mandatory = $true)]$StartDate,
        [Parameter(Mandatory = $true)]$EndDate,
        [Parameter(Mandatory = $true)]$ExportPath,
        [Parameter(Mandatory = $true)]$ResultSize
    )

    Get-MessageTrackingLog -Start "$StartDate" -End "$EndDate" -ResultSize $ResultSize |
        Select-Object Timestamp, Sender, {$_.Recipients}, Directionality, MessageSubject, Source, EventID, TotalBytes, SourceContext, ServerIP, ClientHostName |
        Export-Csv -path $ExportPath
}

Function Get-Management {

    <#
    .SYNOPSIS
    -Taylor Lee
    Modified 05172019
 
    .DESCRIPTION
    Opens Computer management connected for another PC
 
    .Example
    Specify the computer you are connecting to.
 
    Get-Management -computer PCName
    #>


    [CmdletBinding()]

    Param (
        [Parameter(Mandatory = $true)]$computer
    )

    compmgmt.msc /computer:$computer

}

Function Get-Mario {
    [System.Console]::Beep(659, 125);
    [System.Console]::Beep(659, 125);
    [System.Threading.Thread]::Sleep(125);
    [System.Console]::Beep(659, 125);
    [System.Threading.Thread]::Sleep(167);
    [System.Console]::Beep(523, 125);
    [System.Console]::Beep(659, 125);
    [System.Threading.Thread]::Sleep(125);
    [System.Console]::Beep(784, 125);
    [System.Threading.Thread]::Sleep(375);
    [System.Console]::Beep(392, 125);
    [System.Threading.Thread]::Sleep(375);
    [System.Console]::Beep(523, 125);
    [System.Threading.Thread]::Sleep(250);
    [System.Console]::Beep(392, 125);
    [System.Threading.Thread]::Sleep(250);
    [System.Console]::Beep(330, 125);
    [System.Threading.Thread]::Sleep(250);
    [System.Console]::Beep(440, 125);
    [System.Threading.Thread]::Sleep(125);
    [System.Console]::Beep(494, 125);
    [System.Threading.Thread]::Sleep(125);
    [System.Console]::Beep(466, 125);
    [System.Threading.Thread]::Sleep(42);
    [System.Console]::Beep(440, 125);
    [System.Threading.Thread]::Sleep(125);
    [System.Console]::Beep(392, 125);
    [System.Threading.Thread]::Sleep(125);
    [System.Console]::Beep(659, 125);
    [System.Threading.Thread]::Sleep(125);
    [System.Console]::Beep(784, 125);
    [System.Threading.Thread]::Sleep(125);
    [System.Console]::Beep(880, 125);
    [System.Threading.Thread]::Sleep(125);
    [System.Console]::Beep(698, 125);
    [System.Console]::Beep(784, 125);
    [System.Threading.Thread]::Sleep(125);
    [System.Console]::Beep(659, 125);
    [System.Threading.Thread]::Sleep(125);
    [System.Console]::Beep(523, 125);
    [System.Threading.Thread]::Sleep(125);
    [System.Console]::Beep(587, 125);
    [System.Console]::Beep(494, 125);
    [System.Threading.Thread]::Sleep(125);
    [System.Console]::Beep(523, 125);
}

Function Get-MissionImpossible {
    [console]::beep(784, 150)
    Start-Sleep -m 300
    [console]::beep(784, 150)
    Start-Sleep -m 300
    [console]::beep(932, 150)
    Start-Sleep -m 150
    [console]::beep(1047, 150)
    Start-Sleep -m 150
    [console]::beep(784, 150)
    Start-Sleep -m 300
    [console]::beep(784, 150)
    Start-Sleep -m 300
    [console]::beep(699, 150)
    Start-Sleep -m 150
    [console]::beep(740, 150)
    Start-Sleep -m 150
    [console]::beep(784, 150)
    Start-Sleep -m 300
    [console]::beep(784, 150)
    Start-Sleep -m 300
    [console]::beep(932, 150)
    Start-Sleep -m 150
    [console]::beep(1047, 150)
    Start-Sleep -m 150
    [console]::beep(784, 150)
    Start-Sleep -m 300
    [console]::beep(784, 150)
    Start-Sleep -m 300
    [console]::beep(699, 150)
    Start-Sleep -m 150
    [console]::beep(740, 150)
    Start-Sleep -m 150
    [console]::beep(932, 150)
    [console]::beep(784, 150)
    [console]::beep(587, 1200)
    Start-Sleep -m 75
    [console]::beep(932, 150)
    [console]::beep(784, 150)
    [console]::beep(554, 1200)
    Start-Sleep -m 75
    [console]::beep(932, 150)
    [console]::beep(784, 150)
    [console]::beep(523, 1200)
    Start-Sleep -m 150
    [console]::beep(466, 150)
    [console]::beep(523, 150)
}

function Get-NetworkStatistics {
    <#
    .SYNOPSIS
        Display current TCP/IP connections for local or remote system
 
    .FUNCTIONALITY
        Computers
 
    .DESCRIPTION
        Display current TCP/IP connections for local or remote system. Includes the process ID (PID) and process name for each connection.
        If the port is not yet established, the port number is shown as an asterisk (*).
 
    .PARAMETER ProcessName
        Gets connections by the name of the process. The default value is '*'.
 
    .PARAMETER Port
        The port number of the local computer or remote computer. The default value is '*'.
 
    .PARAMETER Address
        Gets connections by the IP address of the connection, local or remote. Wildcard is supported. The default value is '*'.
 
    .PARAMETER Protocol
        The name of the protocol (TCP or UDP). The default value is '*' (all)
 
    .PARAMETER State
        Indicates the state of a TCP connection. The possible states are as follows:
 
        Closed - The TCP connection is closed.
        Close_Wait - The local endpoint of the TCP connection is waiting for a connection termination request from the local user.
        Closing - The local endpoint of the TCP connection is waiting for an acknowledgement of the connection termination request sent previously.
        Delete_Tcb - The transmission control buffer (TCB) for the TCP connection is being deleted.
        Established - The TCP handshake is complete. The connection has been established and data can be sent.
        Fin_Wait_1 - The local endpoint of the TCP connection is waiting for a connection termination request from the remote endpoint or for an acknowledgement of the connection termination request sent previously.
        Fin_Wait_2 - The local endpoint of the TCP connection is waiting for a connection termination request from the remote endpoint.
        Last_Ack - The local endpoint of the TCP connection is waiting for the final acknowledgement of the connection termination request sent previously.
        Listen - The local endpoint of the TCP connection is listening for a connection request from any remote endpoint.
        Syn_Received - The local endpoint of the TCP connection has sent and received a connection request and is waiting for an acknowledgment.
        Syn_Sent - The local endpoint of the TCP connection has sent the remote endpoint a segment header with the synchronize (SYN) control bit set and is waiting for a matching connection request.
        Time_Wait - The local endpoint of the TCP connection is waiting for enough time to pass to ensure that the remote endpoint received the acknowledgement of its connection termination request.
        Unknown - The TCP connection state is unknown.
 
        Values are based on the TcpState Enumeration:
        http://msdn.microsoft.com/en-us/library/system.net.networkinformation.tcpstate%28VS.85%29.aspx
 
        Cookie Monster - modified these to match netstat output per here:
        http://support.microsoft.com/kb/137984
 
    .PARAMETER ComputerName
        If defined, run this command on a remote system via WMI. \\computername\c$\netstat.txt is created on that system and the results returned here
 
    .PARAMETER ShowHostNames
        If specified, will attempt to resolve local and remote addresses.
 
    .PARAMETER tempFile
        Temporary file to store results on remote system. Must be relative to remote system (not a file share). Default is "C:\netstat.txt"
 
    .PARAMETER AddressFamily
        Filter by IP Address family: IPv4, IPv6, or the default, * (both).
 
        If specified, we display any result where both the localaddress and the remoteaddress is in the address family.
 
    .EXAMPLE
        Get-NetworkStatistics | Format-Table
 
    .EXAMPLE
        Get-NetworkStatistics iexplore -computername k-it-thin-02 -ShowHostNames | Format-Table
 
    .EXAMPLE
        Get-NetworkStatistics -ProcessName md* -Protocol tcp
 
    .EXAMPLE
        Get-NetworkStatistics -Address 192* -State LISTENING
 
    .EXAMPLE
        Get-NetworkStatistics -State LISTENING -Protocol tcp
 
    .EXAMPLE
        Get-NetworkStatistics -Computername Computer1, Computer2
 
    .EXAMPLE
        'Computer1', 'Computer2' | Get-NetworkStatistics
 
    .EXAMPLE
        Get-NetworkStatistics | where {$_.LocalAddress -like "192.168.240.8"} | sort processname | ft
 
    .OUTPUTS
        System.Management.Automation.PSObject
 
    .NOTES
        Author: Shay Levy, code butchered by Cookie Monster
        Shay's Blog: http://PowerShay.com
        Cookie Monster's Blog: http://ramblingcookiemonster.github.io/
 
    .LINK
        http://gallery.technet.microsoft.com/scriptcenter/Get-NetworkStatistics-66057d71
    #>


    [OutputType('System.Management.Automation.PSObject')]
    [CmdletBinding()]
    param(

        [Parameter(Position = 0)]
        [System.String]$ProcessName = '*',

        [Parameter(Position = 1)]
        [System.String]$Address = '*',

        [Parameter(Position = 2)]
        $Port = '*',

        [Parameter(Position = 3,
            ValueFromPipeline = $True,
            ValueFromPipelineByPropertyName = $True)]
        [System.String[]]$ComputerName = $env:COMPUTERNAME,

        [ValidateSet('*', 'tcp', 'udp')]
        [System.String]$Protocol = '*',

        [ValidateSet('*', 'Closed', 'Close_Wait', 'Closing', 'Delete_Tcb', 'DeleteTcb', 'Established', 'Fin_Wait_1', 'Fin_Wait_2', 'Last_Ack', 'Listening', 'Syn_Received', 'Syn_Sent', 'Time_Wait', 'Unknown')]
        [System.String]$State = '*',

        [switch]$ShowHostnames,

        [switch]$ShowProcessNames = $true,

        [System.String]$TempFile = "C:\netstat.txt",

        [validateset('*', 'IPv4', 'IPv6')]
        [string]$AddressFamily = '*'
    )

    begin {
        #Define properties
        $properties = 'ComputerName', 'Protocol', 'LocalAddress', 'LocalPort', 'RemoteAddress', 'RemotePort', 'State', 'ProcessName', 'PID'

        #store hostnames in array for quick lookup
        $dnsCache = @{}

    }

    process {

        foreach ($Computer in $ComputerName) {

            #Collect processes
            if ($ShowProcessNames) {
                Try {
                    $processes = Get-Process -ComputerName $Computer -ErrorAction stop | Select-Object name, id
                }
                Catch {
                    Write-warning "Could not run Get-Process -computername $Computer. Verify permissions and connectivity. Defaulting to no ShowProcessNames"
                    $ShowProcessNames = $false
                }
            }

            #Handle remote systems
            if ($Computer -ne $env:COMPUTERNAME) {

                #define command
                [string]$cmd = "cmd /c c:\windows\system32\netstat.exe -ano >> $tempFile"

                #define remote file path - computername, drive, folder path
                $remoteTempFile = "\\{0}\{1}`${2}" -f "$Computer", (split-path $tempFile -qualifier).TrimEnd(":"), (Split-Path $tempFile -noqualifier)

                #delete previous results
                Try {
                    $null = Invoke-WmiMethod -class Win32_process -name Create -ArgumentList "cmd /c del $tempFile" -ComputerName $Computer -ErrorAction stop
                }
                Catch {
                    Write-Warning "Could not invoke create win32_process on $Computer to delete $tempfile"
                }

                #run command
                Try {
                    $processID = (Invoke-WmiMethod -class Win32_process -name Create -ArgumentList $cmd -ComputerName $Computer -ErrorAction stop).processid
                }
                Catch {
                    #If we didn't run netstat, break everything off
                    Throw $_
                    Break
                }

                #wait for process to complete
                while (
                    #This while should return true until the process completes
                    $(
                        try {
                            get-process -id $processid -computername $Computer -ErrorAction Stop
                        }
                        catch {
                            $FALSE
                        }
                    )
                ) {
                    start-sleep -seconds 2
                }

                #gather results
                if (test-path $remoteTempFile) {

                    Try {
                        $results = Get-Content $remoteTempFile | Select-String -Pattern '\s+(TCP|UDP)'
                    }
                    Catch {
                        Throw "Could not get content from $remoteTempFile for results"
                        Break
                    }

                    Remove-Item $remoteTempFile -force

                }
                else {
                    Throw "'$tempFile' on $Computer converted to '$remoteTempFile'. This path is not accessible from your system."
                    Break
                }
            }
            else {
                #gather results on local PC
                $results = netstat -ano | Select-String -Pattern '\s+(TCP|UDP)'
            }

            #initialize counter for progress
            $totalCount = $results.count
            $count = 0

            #Loop through each line of results
            foreach ($result in $results) {

                $item = $result.line.split(' ', [System.StringSplitOptions]::RemoveEmptyEntries)

                if ($item[1] -notmatch '^\[::') {

                    #parse the netstat line for local address and port
                    if (($la = $item[1] -as [ipaddress]).AddressFamily -eq 'InterNetworkV6') {
                        $localAddress = $la.IPAddressToString
                        $localPort = $item[1].split('\]:')[-1]
                    }
                    else {
                        $localAddress = $item[1].split(':')[0]
                        $localPort = $item[1].split(':')[-1]
                    }

                    #parse the netstat line for remote address and port
                    if (($ra = $item[2] -as [ipaddress]).AddressFamily -eq 'InterNetworkV6') {
                        $remoteAddress = $ra.IPAddressToString
                        $remotePort = $item[2].split('\]:')[-1]
                    }
                    else {
                        $remoteAddress = $item[2].split(':')[0]
                        $remotePort = $item[2].split(':')[-1]
                    }

                    #Filter IPv4/IPv6 if specified
                    if ($AddressFamily -ne "*") {
                        if ($AddressFamily -eq 'IPv4' -and $localAddress -match ':' -and $remoteAddress -match ':|\*' ) {
                            #Both are IPv6, or ipv6 and listening, skip
                            Write-Verbose "Filtered by AddressFamily:`n$result"
                            continue
                        }
                        elseif ($AddressFamily -eq 'IPv6' -and $localAddress -notmatch ':' -and ( $remoteAddress -notmatch ':' -or $remoteAddress -match '*' ) ) {
                            #Both are IPv4, or ipv4 and listening, skip
                            Write-Verbose "Filtered by AddressFamily:`n$result"
                            continue
                        }
                    }

                    #parse the netstat line for other properties
                    $procId = $item[-1]
                    $proto = $item[0]
                    $status = if ($item[0] -eq 'tcp') {$item[3]} else {$null}

                    #Filter the object
                    if ($remotePort -notlike $Port -and $localPort -notlike $Port) {
                        write-verbose "remote $Remoteport local $localport port $port"
                        Write-Verbose "Filtered by Port:`n$result"
                        continue
                    }

                    if ($remoteAddress -notlike $Address -and $localAddress -notlike $Address) {
                        Write-Verbose "Filtered by Address:`n$result"
                        continue
                    }

                    if ($status -notlike $State) {
                        Write-Verbose "Filtered by State:`n$result"
                        continue
                    }

                    if ($proto -notlike $Protocol) {
                        Write-Verbose "Filtered by Protocol:`n$result"
                        continue
                    }

                    #Display progress bar prior to getting process name or host name
                    Write-Progress  -Activity "Resolving host and process names"`
                        -Status "Resolving process ID $procId with remote address $remoteAddress and local address $localAddress"`
                        -PercentComplete (( $count / $totalCount ) * 100)

                    #If we are running showprocessnames, get the matching name
                    if ($ShowProcessNames -or $PSBoundParameters.ContainsKey -eq 'ProcessName') {

                        #handle case where process spun up in the time between running get-process and running netstat
                        if ($procName = $processes | Where-Object {$_.id -eq $procId} | Select-Object -ExpandProperty name ) { }
                        else {$procName = "Unknown"}

                    }
                    else {$procName = "NA"}

                    if ($procName -notlike $ProcessName) {
                        Write-Verbose "Filtered by ProcessName:`n$result"
                        continue
                    }

                    #if the showhostnames switch is specified, try to map IP to hostname
                    if ($showHostnames) {
                        $tmpAddress = $null
                        try {
                            if ($remoteAddress -eq "127.0.0.1" -or $remoteAddress -eq "0.0.0.0") {
                                $remoteAddress = $Computer
                            }
                            elseif ($remoteAddress -match "\w") {

                                #check with dns cache first
                                if ($dnsCache.containskey( $remoteAddress)) {
                                    $remoteAddress = $dnsCache[$remoteAddress]
                                    write-verbose "using cached REMOTE '$remoteAddress'"
                                }
                                else {
                                    #if address isn't in the cache, resolve it and add it
                                    $tmpAddress = $remoteAddress
                                    $remoteAddress = [System.Net.DNS]::GetHostByAddress("$remoteAddress").hostname
                                    $dnsCache.add($tmpAddress, $remoteAddress)
                                    write-verbose "using non cached REMOTE '$remoteAddress`t$tmpAddress"
                                }
                            }
                        }
                        catch { }

                        try {

                            if ($localAddress -eq "127.0.0.1" -or $localAddress -eq "0.0.0.0") {
                                $localAddress = $Computer
                            }
                            elseif ($localAddress -match "\w") {
                                #check with dns cache first
                                if ($dnsCache.containskey($localAddress)) {
                                    $localAddress = $dnsCache[$localAddress]
                                    write-verbose "using cached LOCAL '$localAddress'"
                                }
                                else {
                                    #if address isn't in the cache, resolve it and add it
                                    $tmpAddress = $localAddress
                                    $localAddress = [System.Net.DNS]::GetHostByAddress("$localAddress").hostname
                                    $dnsCache.add($localAddress, $tmpAddress)
                                    write-verbose "using non cached LOCAL '$localAddress'`t'$tmpAddress'"
                                }
                            }
                        }
                        catch { }
                    }

                    #Write the object
                    New-Object -TypeName PSObject -Property @{
                        ComputerName  = $Computer
                        PID           = $procId
                        ProcessName   = $procName
                        Protocol      = $proto
                        LocalAddress  = $localAddress
                        LocalPort     = $localPort
                        RemoteAddress = $remoteAddress
                        RemotePort    = $remotePort
                        State         = $status
                    } | Select-Object -Property $properties

                    #Increment the progress counter
                    $count++
                }
            }
        }
    }
}

Function Get-PasswordExpired {

    <#
    .SYNOPSIS
    -Taylor Lee
    Modified 05172019
 
    .DESCRIPTION
    Returns a list of Active Directory Accounts with expired passwords
 
    .NOTES
    Requires the Active Directory Module.
    #>


    [CmdletBinding()]
    param (
    )

    import-module ActiveDirectory

    Search-ADAccount -PasswordExpired | Select-Object name | Sort-Object name | Format-List

}

Function Get-PCInfo {

    <#
    .Synopsis
    -Taylor Lee
    Modified 05172019
 
    .Description
    Returns useful informaion on the local endpoint or another.
    .NOTES
    Requires Powershell 5.1
 
    .EXAMPLE
    Returns PCinfo for the local computer
 
    Get-PCinfo
 
    .EXAMPLE
    Returns PCinfo for a remote computer
 
    Get-PCinfo -computer PCName
    #>


    [CmdletBinding()]

    #Prompts for Computer Name
    Param (
        $Computer
    )


    #Variables
    $SystemEnclosure = get-ciminstance win32_systemenclosure -computername $computer
    $OS = Get-CimInstance Win32_OperatingSystem -Computername $Computer


    #Creating Hash table from variables
    $PCInfo = @{
        Manufacturer   = $SystemEnclosure.Manufacturer
        PCName         = $OS.CSName
        OS             = $OS.Caption
        Architecture   = $OS.OSArchitecture
        AssetTag       = $systemenclosure.serialnumber;
        OSVersion      = $OS.Version
        InstallDate    = $OS.InstallDate
        LastBootUpTime = $OS.LastBootUpTime
    }

    #Writing to Host
    Write-host " "
    Write-host "Computer Info" -Foregroundcolor Cyan
    Write-host "If not run on a Dell machine AssetTag is the Serial Number" -Foregroundcolor Yellow

    #Display Hash Table
    $PCInfo.getenumerator() | Sort-Object -property name | Format-Table -autosize

    #Writing to Host
    Write-host "Computer Disk Info" -Foregroundcolor Cyan

    #Display Drives
    Get-CimInstance win32_logicaldisk -filter "drivetype=3" -computer $computer |
    Format-Table -Property DeviceID, Volumename, `
    @{Name = "SizeGB"; Expression = { [math]::Round($_.Size / 1GB) } }, `
    @{Name = "FreeGB"; Expression = { [math]::Round($_.Freespace / 1GB, 2) } }, `
    @{Name = "PercentFree"; Expression = { [math]::Round(($_.Freespace / $_.size) * 100, 2) } }

    #Writing to Host
    Write-host "Network Information" -Foregroundcolor Cyan

    Get-CimInstance win32_networkadapterconfiguration -computer $computer | Where-Object { $_.IPAddress -ne $null } |
    Select-Object IPAddress, DefaultIPGateway, DNSServerSearchOrder, IPSubnet, MACAddress, Caption, DHCPEnabled, DHCPServer, DNSDomainSuffixSearchOrder |
    Format-List

}

Function Get-Printers {

    <#
    .Synopsis
    -Taylor Lee
    Modified 05172019
 
    .DESCRIPTION
    This command returns a list of local or remote printers
 
    .EXAMPLE
    Returns printers for the local computer only.
 
    Get-Printers
 
    .EXAMPLE
    -Computer is used to pull printers from remote computers.
 
    Get-Printers -computer PCName
    #>


    [CmdletBinding()]

    Param (
        [Parameter(Position = 1)]$computer
    )


    get-ciminstance cim_printer -computer $computer | Select-Object Name, Drivername, Portname | Sort-Object name | Format-Table -autosize
}

Function Get-PrintManagement {

    <#
    .SYNOPSIS
    -Taylor Lee
    Modified 05172019
 
    .DESCRIPTION
    Opens Print Management
    #>


    [CmdletBinding()]
    param (
    )
    printmanagement.msc
}

Function Get-PublicIP {

    <#
    .SYNOPSIS
    -Taylor Lee
    Modified 05172019
 
    .DESCRIPTION
    Returns WhoIS public IP info for your location or any specified public IP
 
    .EXAMPLE
    Returns local Public IP Info
 
    Get-PublicIP
 
    .Example
    Returns your Public IP Info
 
    Get-PublicIP -IP 8.8.8.8
    #>


    [CmdletBinding()]
    Param (
        [Parameter(Position = 0)]$IP
    )

    $ipinfo = Invoke-RestMethod http://ipinfo.io/$IP
    $PublicIP = @{
        IP       = $ipinfo.ip
        Hostname = $ipinfo.hostname
        City     = $ipinfo.city
        Region   = $ipinfo.region
        country  = $ipinfo.country
        loc      = $ipinfo.loc
        org      = $ipinfo.org
        Phone    = $ipinfo.phone
    }
    $PublicIP.getenumerator() | Sort-Object -property name

}

Function Get-Tetris {
    [Console]::Beep(658, 125);
    [Console]::Beep(1320, 500);
    [Console]::Beep(990, 250);
    [Console]::Beep(1056, 250);
    [Console]::Beep(1188, 250);
    [Console]::Beep(1320, 125);
    [Console]::Beep(1188, 125);
    [Console]::Beep(1056, 250);
    [Console]::Beep(990, 250);
    [Console]::Beep(880, 500);
    [Console]::Beep(880, 250);
    [Console]::Beep(1056, 250);
    [Console]::Beep(1320, 500);
    [Console]::Beep(1188, 250);
    [Console]::Beep(1056, 250);
    [Console]::Beep(990, 750);
    [Console]::Beep(1056, 250);
    [Console]::Beep(1188, 500);
    [Console]::Beep(1320, 500);
    [Console]::Beep(1056, 500);
    [Console]::Beep(880, 500);
    [Console]::Beep(880, 500);
}

Function Get-UserDisabledMailboxes {
    <#
    .SYNOPSIS
    -Taylor Lee
    Modified 05172019
 
    .DESCRIPTION
    Create a csv list for mailboxes associated with disabled AD Accounts
 
    .NOTES
    Requires the Active Directory module and must be run from the Exchange Server
    #>


    [CmdletBinding(SupportsShouldProcess)]

    Param (
        [Parameter(Mandatory = $true)]$Path
    )

    Get-User -RecipientTypeDetails UserMailbox |
    Where-Object { $_.UserAccountControl -like "*accountdisabled*" } |
    Export-CSV $Path
}

Function Get-UserReport {

    <#
    .SYNOPSIS
    -Taylor Lee
    Modified 05172019
 
    .DESCRIPTION
    Create a report of Active Directory users
 
    .NOTES
    Requires Active Directory Module
 
    .Example
    Specify is where the report is to be saved.
 
    Get-UserReport -path C:\UserReport.csv
    #>


    [CmdletBinding(SupportsShouldProcess)]

    Param (
        [Parameter(Mandatory = $true)]$Path
    )

    Import-Module ActiveDirectory

    get-aduser -Filter * -properties * |
    Select-Object CN, DistinguishedName, SamAccountName, Modified, PasswordLastSet, PasswordNeverExpires, LockedOut, LastBadPasswordAttempt, BadLogonCount, Created, EmailAddress, { $_.proxyAddresses }, mailNickname, Enabled, HomeDirectory, HomeDrive |
    Export-CSV $Path -NoTypeInformation
}

Function Get-VirtualDirectories {

    <#
    .SYNOPSIS
    -Taylor Lee
    Modified 05172019
 
    .DESCRIPTION
    Returns a list of Virtual Directories
 
    .NOTES
    Requires the Microsoft Exchange module.
    #>


    [CmdletBinding()]
    param (
    )

    Write-Host "Powershell Virtual Directories"   -Foregroundcolor Green
    Get-PowerShellVirtualDirectory | Format-List internalurl, externalurl
    Write-Host "Active-Sync Virtual Directories"  -Foregroundcolor Green
    Get-ActiveSyncVirtualDirectory | Format-List internalurl, externalurl
    Write-Host "Web Services Virtual Directories"    -Foregroundcolor Green
    Get-WebServicesVirtualDirectory | Format-List internalurl, externalurl
    Write-Host "OWA Virtual Directories"    -Foregroundcolor Green
    Get-OwaVirtualDirectory | Format-List internalurl, externalurl
    Write-Host "AutoDiscover Virtual Directories"   -Foregroundcolor Green
    Get-AutodiscoverVirtualDirectory | Format-List internalurl, externalurl
    Write-Host "ECP Virtual Directories"    -Foregroundcolor Green
    Get-EcpVirtualDirectory | Format-List internalurl, externalurl
    Write-Host "OAB Virtual Directories"    -Foregroundcolor Green
    Get-OABvirtualDirectory | Format-List internalurl, externalurl
    Write-Host "MAPI Virtual Directories"    -Foregroundcolor Green
    get-mapivirtualdirectory | Format-List internalurl,externalurl
}

Function Get-Weather {
    <#
    .Synopsis
    Modified 05182019
    Taylor Lee
    Made Using api from http://wttr.in/
 
    .Description
    Shows weather for a location or the moon phase
 
    .Notes
    For help modifying the function
 
    http://wttr.in/:help
 
    https://winaero.com/blog/get-weather-forecast-powershell/
 
    .Example
    Multiple Location Options Available
 
    Get-Weather -Location houston+texas
 
    paris # city name
    Eiffel+tower # any location
    muc # airport code (3 letters)
    94107 # area codes
    moon # Moon phase (add ,+US or ,+France for these cities)
    moon@2016-10-25 # Moon phase for the date (@2016-10-25)
    #>


    [Cmdletbinding()]
    Param(
        [Parameter(Mandatory = $true)]$Location
    )

    (Invoke-WebRequest http://wttr.in/"$Location"?QF -UserAgent "curl" ).Content
}

Function Remove-All {

    <#
    .Synopsis
    -Taylor Lee
    Modified 05172019
 
    .Description
    This Command removes log files, temp files, and empties the recycle bin. Access denied errors do not indicate a failue of the script. Run for the local or a remote PC.
 
    .EXAMPLE
    Free up space on the local computer
 
    Remove-All
 
    .EXAMPLE
    Free up space on a remote PC. May be more effective if run locally depending on in place security.
 
    Remove-All -Computer JackPC10
    #>


    [CmdletBinding(SupportsShouldProcess)]
    param (
        [Parameter()]$computer
    )

    #Statement of Free Space before Cleaning
    Write-Host " "
    Write-Host "Free Space Before Cleaning" -ForegroundColor Yellow
    Get-CimInstance win32_logicaldisk -filter "drivetype=3" -computer $computer |
    Format-Table -Property DeviceID, Volumename, `
    @{Name = "SizeGB"; Expression = { [math]::Round($_.Size / 1GB) } }, `
    @{Name = "FreeGB"; Expression = { [math]::Round($_.Freespace / 1GB, 2) } }, `
    @{Name = "PercentFree"; Expression = { [math]::Round(($_.Freespace / $_.size) * 100, 2) } }

    #Statement that the function is freeing up space
    Write-Host "Freeing up space. Enjoy your Coffee!" -BackgroundColor Black -ForegroundColor Green

    #Free up space on the local or remote computer
    if ($computer -ne $null) {
        $ErrorActionPreference = 'SilentlyContinue'

        Get-ChildItem -path "\\$computer\C$\windows\logs" -Include '*.log' -Recurse -force | Remove-Item -force -Recurse
        Get-ChildItem -path "\\$computer\C$\windows\logs" -Include '*.cab' -Recurse -force | Remove-Item -force -Recurse
        Get-ChildItem -path "\\$computer\C$\ProgramData\Microsoft\Windows\WER" -Include '*.*' -Recurse -force | Remove-Item -force -Recurse
        Get-ChildItem -path "\\$computer\C$\$recycle.bin" -Include '*' -Recurse -force | Remove-Item -force -Recurse
        $tempfolders = @("\\$computer\C$\Windows\Temp\*", "\\$computer\C$\Windows\Prefetch\*", "\\$computer\C$\Documents and Settings\*\Local Settings\temp\*", "\\$computer\C$\Users\*\Appdata\Local\Temp\*")
        Remove-Item $tempfolders -force -recurse
        $tempinternetfolders = @("\\$computer\C$\Users\*\Appdata\Local\Microsoft\Windows\INetCache\*", "\\$computer\C$\Users\*\Appdata\Local\Microsoft\Windows\Cookies\*")
        Remove-Item $tempinternetfolders -force -recurse
        $ErrorActionPreference = 'Continue'

        Write-Host " "
        Write-Host "Free Space After Cleaning" -ForegroundColor Yellow
        Get-CimInstance win32_logicaldisk -filter "drivetype=3" -computer $computer |
        Format-Table -Property DeviceID, Volumename, `
        @{Name = "SizeGB"; Expression = { [math]::Round($_.Size / 1GB) } }, `
        @{Name = "FreeGB"; Expression = { [math]::Round($_.Freespace / 1GB, 2) } }, `
        @{Name = "PercentFree"; Expression = { [math]::Round(($_.Freespace / $_.size) * 100, 2) } }
    }

    else {
        $ErrorActionPreference = 'SilentlyContinue'

        Get-ChildItem -path "C:\windows\" -Include '*.log' -Recurse -force | Remove-Item -force -Recurse
        Get-ChildItem -path "C:\windows\logs" -Include '*.cab' -Recurse -force | Remove-Item -force -Recurse
        Get-ChildItem -path "C:\ProgramData\Microsoft\Windows\WER" -Include '*.*' -Recurse -force | Remove-Item -force -Recurse
        Get-ChildItem -path "c:\$recycle.bin" -Include '*' -Recurse -force | Remove-Item -force -Recurse
        $tempfolders = @("C:\Windows\Temp\*", "C:\Windows\Prefetch\*", "C:\Documents and Settings\*\Local Settings\temp\*", "C:\Users\*\Appdata\Local\Temp\*")
        Remove-Item $tempfolders -force -recurse
        $tempinternetfolders = @("C:\Users\*\Appdata\Local\Microsoft\Windows\INetCache\*", "C:\Users\*\Appdata\Local\Microsoft\Windows\Cookies\*")
        Remove-Item $tempinternetfolders -force -recurse
        powercfg.exe /hibernate off
        Remove-Item c:\hiberfil.sys -force
        $ErrorActionPreference = 'Continue'

        Write-Host " "
        Write-Host "Free Space After Cleaning" -ForegroundColor Yellow
        Get-CimInstance win32_logicaldisk -filter "drivetype=3" -computer $computer |
        Format-Table -Property DeviceID, Volumename, `
        @{Name = "SizeGB"; Expression = { [math]::Round($_.Size / 1GB) } }, `
        @{Name = "FreeGB"; Expression = { [math]::Round($_.Freespace / 1GB, 2) } }, `
        @{Name = "PercentFree"; Expression = { [math]::Round(($_.Freespace / $_.size) * 100, 2) } }
    }

}

Function Remove-AppName {

    <#
    .Synopsis
    -Taylor Lee
    Modified 05172019
 
    .DESCRIPTION
    This command uninstalls an application. Good for when elevation privleges are needed from a user session.
 
    .EXAMPLE
    Specifiy the installed application being uninstalled. The full application name must be used.
 
    Remove-AppName -appname 'App Name has spaces'
    #>


    [CmdletBinding()]

    Param (
        [Parameter(Mandatory = $true)]$Appname
    )

    wmic product where name="$Appname" call uninstall
}

Function Remove-AppNameLike {

    <#
    .Synopsis
    -Taylor Lee
    Modified 05172019
 
    .DESCRIPTION
    This command uninstalls an application. Good for when elevation privleges are needed from a user session.
 
    .EXAMPLE
    Specifiy the installed application being uninstalled. You can provide only part of the applicaiton name.
    If other applications share the partial appname provided they will be unisntalled also.
 
    Remove-AppName -appnamelike 'partial app name'
    #>


    [CmdletBinding()]

    Param (
        [Parameter(Mandatory = $true)]$Appnamelike
    )

    wmic product where "name like '%$Appnamelike%'" call uninstall
}

Function Remove-DisabledADProfiles {

    <#
    .Synopsis
    -Taylor Lee
    Modified 05172019
 
    .Description
    This function leverages PSRemoting to import the AD module a active domain controller.
    It will then parse through existing profiles on the local machine to make sure they don't belong to disabled or missing Active Directory Accounts
    If a prfoile mathces a missing or disable Active Directroy account it will be deleted on the local client.
 
    .Notes
    This Function requires Powershell Remoting be enabled on the leveraged domain controller. If PSRemoting is disabled run the command <Enable-PSRemoting -force> on the domain controller
 
    .EXAMPLE
    Use Computername to specify the Domain Controller to be queried for active domain accounts
 
    Remove-DisabledADProfiles -domaincontroller DomainControllerDNSName
    #>


    [CmdletBinding()]

    Param (
        [Parameter(Position = 0, Mandatory = $true)]$domaincontroller
    )

    $DCSession = New-PSSession -Computername $domaincontroller
    Invoke-Command -Command { Import-Module ActiveDirectory } -Session $DCSession
    Import-PSSession -Session $DCSession -Module ActiveDirectory -allowclobber

    $profiles = Get-WmiObject -Class Win32_UserProfile
    foreach ($prof in $profiles) {
        $sid = $prof.sid
        $ADUser = Get-ADUser -Filter * | where-object sid -eq $sid
        if ($ADUser.enabled -eq $false) {
            #delete profile
            "Delete $($ADUser.name)"
            $prof.delete()
        }


    }

}

Function Remove-OlderThan {

    <#
    .Synopsis
    -Taylor Lee
    Modified 05172019
 
    .Description
    This scripts function is to delete files and folders older than x days recursivley.
 
    .Example
    Delete-OlderThan -Path "C:\Folder" -DaysBack "-90"
    #>


    Param (
        [Parameter(Mandatory = $true)]$Path,
        [Parameter(Mandatory = $true)][ValidateScript( { $_ -lt 0 })][int]$Daysback,
        [Parameter(Mandatory = $false)][Switch]$Recurse
    )

    if ($Recurse) {
        $CurrentDate = Get-Date
        $DatetoDelete = $CurrentDate.AddDays($Daysback)
        Get-ChildItem $Path -Recurse | Where-Object { $_.LastWriteTime -lt $DatetoDelete } | Remove-Item -Force
    }

    else {
        $CurrentDate = Get-Date
        $DatetoDelete = $CurrentDate.AddDays($Daysback)
        Get-ChildItem $Path | Where-Object { $_.LastWriteTime -lt $DatetoDelete } | Remove-Item -Force
    }

}

Function Remove-Path {

    <#
    .Synopsis
    -Taylor Lee
    Modified 05172019
 
    .DESCRIPTION
    This command deletes all files recursively in a path that match the included filename.
 
    .EXAMPLE
    Specify the parent folder from which the command runs and specify file names to include. Wildcards are supported.
 
    Remove-Path -path c:\Folder -include "*.logs"
    #>


    [CmdletBinding(SupportsShouldProcess)]

    Param (
        [Parameter(Mandatory = $true)]$Path,
        [Parameter(Mandatory = $true)]$Include
    )

    Get-ChildItem -path "$Path" -Include "$Include" -Recurse -force | Remove-Item -force -Recurse
}

Function Remove-PrintQueue {

    <#
    .Synopsis
    -Taylor Lee
    Modified 05172019
 
    .DESCRIPTION
    This command clears print queues for all printers
    #>


    [CmdletBinding(SupportsShouldProcess)]
    param (
    )

    $printers = Get-Printer
    foreach ($printer in $printers) {
        $printjobs = Get-PrintJob -PrinterObject $printer
        foreach ($printjob in $printjobs) {
            Remove-PrintJob -InputObject $printjob
        }
    }

}

Function Reset-NetworkAdapter {

    <#
    .SYNOPSIS
    -Taylor Lee
    Modified 05172019
 
    .DESCRIPTION
    Reset a specified interface
 
    .EXAMPLE
    Reset-NetworkAdapter -interface "Local Area Connection"
    #>


    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]$Interface
    )

    netsh interface set interface $Interface admin=disable
    netsh interface set interface $Interface admin=enable
}

Function Reset-NetworkStack {

    <#
    .SYNOPSIS
    -Taylor Lee
    Modified 05172019
 
    .DESCRIPTION
    Resets the TCP/IP and Winsock Stacks
    #>


    [CmdletBinding()]
    param (
    )

    netsh winsock reset
    netsh int ip reset
    netsh int ipv4 reset reset.log
    netsh int ipv6 reset reset.log
    Write-Host "You need to restart the computer now"  -foregroundcolor yellow
}

Function Restart-Endpoint {

    <#
    .SYNOPSIS
    -Taylor Lee
    Modified 05172019
 
    .DESCRIPTION
    Sets a countdown to restart the Endpoint. The command uses a multiplier set to 1 hour.
    You can use decimals to return shorter than an hour restart times or get X hours and X minutes.
 
    .NOTES
    The parameter must be typed when entering the command and not after. If you typed the command and then entered the parameter when prompted the command will fail.
 
    When using decimal values understand that the value is multiplying against the number of seconds in an hour.
    So all multiplication needs to be done as a fraction of 1. Don't try thinking that it needs to be done against the value of 60 for seconds or hours.
    View the Examples for clarification.
 
    .EXAMPLE
    Restarts the Endpoint in 5 Hours
 
    Restart-Endpoint -Hours 5
 
    .EXAMPLE
    Restarts the Endpoint in 5 hours and 15 minutes
 
    Restart-Endpoint -Hours 5.25
 
    .EXAMPLE
    Restarts the Endpoint in 15 minutes
 
    Restart-Endpoint -Hours 0.25
    #>


    [CmdletBinding()]

    Param (
        [Parameter(Mandatory = $true)]$Hours
    )

    $Hoursmultiplied = $Hours * 3600

    Shutdown /r /t $Hoursmultiplied
}

Function Set-Password {

    <#
    .SYNOPSIS
    -Taylor Lee
    Modified 05172019
 
    .DESCRIPTION
    Sets a Active Directory Password and provides an option to require a password change on login
 
    .NOTES
    Requires the Active Directory Module
 
    .EXAMPLE
    Specifies the username being set and then prompts for a password.
 
    Set-Password -username domain\username
    #>

    [CmdletBinding()]

    Param (
        [Parameter(Mandatory = $true)]$Username,
        [Parameter(Mandatory = $true)][SecureString]$Password
    )

    Import-Module ActiveDirectory

    Set-ADAccountPassword -identity $username -Reset -NewPassword $Password

    $Prompt = Read-Host "Require a Password Change? Type Yes or No."

    if ($Prompt -eq 'Yes') {
        Set-ADUser -Identity $Username -ChangePasswordAtLogon $true
    }
    else {
        Write-Host "You specified no" -ForegroundColor Yellow
    }
}

Function Start-AzureSync {

    <#
    .SYNOPSIS
    -Taylor Lee
    Modified 05172019
 
    .DESCRIPTION
    Starts a local Active Directory sync to Azure Active Directory.
 
    .NOTES
    Must be run from the Domain Controller that has Azure AD Connect.
 
    .Example
    Performs a full sync with Azure Active Directory
 
    Start-AzureSync -Policy Initial
 
    .EXAMPLE
    Performs an incrmental sync with Azure Active Directroy
 
    Start-AzureSync -Policy Delta
    #>


    [CmdletBinding()]

    Param (
        [Parameter(Mandatory = $true)]$Policy
    )

    Start-ADSyncSyncCycle -PolicyType $Policy
}

Function Unlock-Account {

    <#
    .SYNOPSIS
    -Taylor Lee
    Modified 05172019
 
    .DESCRIPTION
    Unlocks an Active Directory Account
 
    .NOTES
    Requires the Active Directory Module.
 
    .Example
    Use Get-lockedAccounts to quickly obtain the identity to use in the command.
 
    Get-LockedAccounts
    Unlock-ADAccount -identity JohnD
    #>


    [CmdletBinding()]

    Param (
        [Parameter(Mandatory = $true)]$Username
    )

    Import-Module ActiveDirectory

    Unlock-ADAccount -identity $username

}

Function Unlock-AllAccounts {

    <#
    .SYNOPSIS
    -Taylor Lee
    Modified 05172019
 
    .DESCRIPTION
    Unlocks all Active Directory Accounts
 
    .NOTES
    Requires the Active Directory Module.
    #>


    [CmdletBinding(SupportsShouldProcess)]
    Param (
    )

    search-adaccount -lockedout | unlock-adaccount
}