Checking if a variable has been submitted to a function

$PSBoundParameters.ContainsKey('Username')

The line above will return true if the ‘Username’ has been provided to the function

https://stackoverflow.com/questions/48643250/how-to-check-if-a-powershell-optional-argument-was-set-by-caller

Function get-TPNUserState() {
    <#
    .Description
    Supplies some sommonly needed values for a user:
    PasswordLastSet, DisplayName, Description, LastLogonDate, Manager, DistinguishedName, whencreated

    .Example
    get-TPNUserState tp-nickel

    .Parameter Username
    The username that you want to look into. If you don't enter one then it will prompt you.

    #>

    [Cmdletbinding()]
    param(
        [Parameter(Position=0)]
        [string]$Username
        )
    process{
         
        if(!$PSBoundParameters.ContainsKey('Username')){ $Username = read-host -Prompt UserName } #if Username is not set then prompt for it.
        Get-ADuser $Username -properties PasswordLastSet, DisplayName, Description, LastLogonDate, Manager, DistinguishedName, whencreated | select SAMAccountName, DisplayName, Description, Enabled, PasswordLastSet, LastLogonDate, whencreated, Manager, DistinguishedName | fl
    }

}

Module Directory in PowerShell

$env:PSModulePath -split ';'

The command above will list the directories that PowerShell will search for installed modules.

There is a difference between VSCode and PowerShell ISE though!

VSCode
PowerShell ISE

Notethat VSCode looks in C:\Users\User\Documents\Powershell\Modules compared with C:\Users\User\Documents\WindowsPowershell\Modules

Credentials in Powershell

http://duffney.io/AddCredentialsToPowerShellFunctions

function Set-RemoteRegistryValue {
    param(
        $ComputerName,
        $Path,
        $Name,
        $Value,
        [ValidateNotNull()]
        [System.Management.Automation.PSCredential]
        [System.Management.Automation.Credential()]
        $Credential = [System.Management.Automation.PSCredential]::Empty        
    )

    if($Credential -ne [System.Management.Automation.PSCredential]::Empty) {
        Invoke-Command -ComputerName:$ComputerName -Credential:$Credential  {
            Set-ItemProperty -Path $using:Path -Name $using:Name -Value $using:Value
        }
    } else {
        Invoke-Command -ComputerName:$ComputerName {
            Set-ItemProperty -Path $using:Path -Name $using:Name -Value $using:Value
        }
    }
}

Debugging and Breakpoints in Powershell

Write-Debug

As long as a script is an advanced script then you can use Write-Debug.

Write-Debug -Message "Enter debug text here, variables can be included."

The script will pause at each Write-Debug and display the debug text, including any variables. This will display the current content of any variables in the debug text.

To run a script with debugging turned on you must run the script with the debug switch.

.\MyTestSwitch.ps1 -debug

Set-PSBreakpoint

Another method for debugging is to set breakpoints prior to running a script.

Set-PSBreakPoint -Script .\MyTestSwitch.ps1 -Line 5
Set-PSBreakPoint -Script .\MyTestSwitch.ps1 -Variable ComputerName 

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/set-psbreakpoint?view=powershell-6

Removing PS-Breakpoints

Get-PSBreakPoint | Remove-PSBreakPoint

Remoting in PowerShell

INVOKE

invoke-command -ComputerName (get-content C:\temp\TestComputers.txt) -ScriptBlock {get-eventlog -LogName Application -Newest 5}

invoke-command -ComputerName (get-adcomputer -filter *) -ScriptBlock {get-eventlog -LogName Application -Newest 5}

PS C:\temp> Enter-PSSession -ComputerName SGEN-TN01

[SGEN-TN01]: PS C:\Users\admin-its-tn\Documents> get-eventlog -LogName Application -Newest 5

   Index Time          EntryType   Source                 InstanceID Message                                                                                                                 

   —– —-          ———   ——                 ———- ——-                                                                                                                 

    3382 Sep 04 12:05  Information SceCli                 1073743528 Security policy in the Group policy objects has been applied successfully.                                              

    3381 Sep 04 12:05  Information gupdate                         0 The description for Event ID ‘0’ in Source ‘gupdate’ cannot be found.  The local computer may not have the necessary r…

    3380 Sep 04 10:59  Information Windows Error Rep…         1001 Fault bucket 1838438238644566740, type 5…                                                                             

    3379 Sep 04 10:35  Information gupdate                         0 The description for Event ID ‘0’ in Source ‘gupdate’ cannot be found.  The local computer may not have the necessary r…

    3378 Sep 04 10:35  0           Software Protecti…   1073742727 The Software Protection service has stopped….                                                                          

[SGEN-TN01]: PS C:\Users\admin-its-tn\Documents> Exit-PSSession

PS C:\temp> 

Returning just the value in PowerShell

This uses “-expand” or “-expanproperty”

Get-ADComputer -filter -searchbase “ou=domain controllers, dc=company,dc=primary”

…this will return a list of computer OBJECTS from the domain controllers OU.

You cannot use this command as a pipeline return….

Get-Service -computerName (Get-ADComputer -filter -searchbase “ou=domain controllers, dc=company,dc=primary”)

As “-ComputerName” is expecting a string and NOT an object. To resolve this we can use the “-expand” to extract a property……

Get-ADComputer -filter -searchbase “ou=domain controllers, dc=company,dc=primary” | Select-Object -expandproperty Name

So, this would work…..

Get-Service -computerName (Get-ADComputer -filter -searchbase “ou=domain controllers, dc=company,dc=primary” | Select-Object -expandproperty Name)

Get-Process -computerName (import-csv .\computers.csv | select-object -expandproperty hostname)