PS: Creating Scripts

2 minute read

Description:

This is a general idea of how to go about creating scripts in Powershell.

To Resolve:

1a. Start with a template script.

  1. Almost all functions will need to have a parameter so the user can specify for their environment. You can let it allow multiple by adding “[]” in the type declaration
[string[]]$ComputerName
  1. Then, in the process block, just loop through each that the user passed. If they only passed one that is fine:
ForEach ($Computer in $ComputerName)
{
# Do something for each individual computer
}
  1. The first steps will be fine enough on their own, but sometimes you want to put each iteration into a table and then return that at the end:

# This is part of my Get-ComputerInfo info script

Foreach ($Computer in $ComputerName)
            {

                If (!([String]::IsNullOrWhiteSpace($Computer)))
                {

                    If (Test-Connection -Quiet -Count 1 -Computer $Computer)
                    {

                        $Progress = @{}
                        $Progress.Activity = "Getting Sytem Information..." 
                        $Progress.Status = ("Percent Complete:" + "{0:N0}" -f ((($i++) / $ComputerName.count) * 100) + "%")
                        $Progress.CurrentOperation = "Processing $($Computer)..."
                        $Progress.PercentComplete = ((($j++) / $ComputerName.count) * 100)
                        Write-Progress @Progress
                    
                    
                        $CimSession = Get-LHSCimSession -ComputerName $Computer -Credential $Credential

                        $computerSystem = Get-CimInstance CIM_ComputerSystem -CimSession $CimSession
                        $computerBIOS = Get-CimInstance CIM_BIOSElement -CimSession $CimSession
                        $computerOS = Get-CimInstance CIM_OperatingSystem -CimSession $CimSession
                        $computerCPU = Get-CimInstance CIM_Processor -CimSession $CimSession
                        $computerHDD = Get-CimInstance Win32_LogicalDisk -Filter "DeviceID = 'C:'" -CimSession $CimSession

                        $ComputerObject = [Ordered]@{}
                        $ComputerObject.ComputerName = $computerSystem.Name
                        $ComputerObject.LastReboot = $computerOS.LastBootUpTime
                        $ComputerObject.OperatingSystem = $computerOS.OSArchitecture + " " + $computerOS.caption
                        $ComputerObject.Model = $computerSystem.Model
                        $ComputerObject.RAM = "{0:N2}" -f [int]($computerSystem.TotalPhysicalMemory / 1GB) + "GB"
                        $ComputerObject.DiskCapacity = "{0:N2}" -f ($computerHDD.Size / 1GB) + "GB"
                        $ComputerObject.TotalDiskSpace = "{0:P2}" -f ($computerHDD.FreeSpace / $computerHDD.Size) + " Free (" + "{0:N2}" -f ($computerHDD.FreeSpace / 1GB) + "GB)"
                        $ComputerObject.CurrentUser = $computerSystem.UserName
                        
                        Log "ComputerName: $($ComputerObject.ComputerName.ToString())"
                        Log "LastReboot: $($ComputerObject.LastReboot.ToString())"
                        Log "OperatingSystem: $($ComputerObject.OperatingSystem.ToString())"
                        Log "Ram: $($ComputerObject.RAM.ToString())"
                        Log "TotalDiskSpace: $($ComputerObject.TotalDiskSpace.ToString())"
                        Log "CurrentUser: $($ComputerObject.CurrentUser.ToString())"
                        Log "####################<Break>####################"

                        $ComputerObjects += $ComputerObject
                        
                        Remove-CimSession -CimSession $CimSession 

                    }

                    Else
                    {
                        Log "Remote computer was not online."
                        $ComputerObject = [Ordered]@{}
                        $ComputerObject.ComputerName = $computer
                        $ComputerObject.LastReboot = "Unable to ping. Make sure the computer is turned on and ICMP inbound ports are opened."
                        $ComputerObject.OperatingSystem = "$null"
                        $ComputerObject.Model = "$null"
                        $ComputerObject.RAM = "$null"
                        $ComputerObject.DiskCapacity = "$null"
                        $ComputerObject.TotalDiskSpace = "$null"
                        $ComputerObject.CurrentUser = "$null"

                        $ComputerObjects += $ComputerObject                     
                    }
                }

                Else
                {
                    Log "Computer name was not in a usable format"
                    $ComputerObject.ComputerName = "Value is null. Make sure computer name is not blank"
                    $ComputerObject.LastReboot = "$Null"
                    $ComputerObject.OperatingSystem = "$null"
                    $ComputerObject.Model = "$null"
                    $ComputerObject.RAM = "$null"
                    $ComputerObject.DiskCapacity = "$null"
                    $ComputerObject.TotalDiskSpace = "$null"
                    $ComputerObject.CurrentUser = "$null"

                    $ComputerObjects += $ComputerObject   
                }
            }

Ignoring the Cim-Session part, what this is doing is looping through one more computers and logging their results into a log file. The first IF block just makes sure you didn’t enter a blank computer name, the second sees if the computer is online, and finally – it processes each computer in the list by connecting to them and putting the results into an object called “$ComputerObject.

But we don’t want to stop there because there can be many computers and we want a list at the end. So what we do is place each $ComputerObject into a $ComputerObjects array. So now, we go back to the Begin block and initialize the array:

$ComputerObjects = @()
  1. Now in the End block, you can just display the results:
$ComputerObjects

This works fine for displaying on a screen, but not to a text file. So we do one last thing instead:

$a = $ComputerObjects | Out-String
Log $a

This is a way to convert an object to a string that way the log will look like what is displayed on the screen.