#Filename: Get-PC.ps1 #This is the primary function for get-pc. All functionality is accessed through this function #See documentation for how to use this module #region Module Import Block $ErrorActionPreference = 'SilentlyContinue' #DevStage can take either Dev or Prod as values $devStage = 'Dev' #Locations for dev build and prod build $getPCDevBuildPath = '\\int.samhealth.net\files\TEAM\SHSISDesktopSolutions\Powershell\Get-PC_Update_2023\Prod\Get-PC\Get-PC.psd1' $getPCProdBuildPath = "\\shscm01\packages\SHS Custom\Get-PC\Prod\Get-PC\Get-PC.psd1" #grabs the version number out of the module manifest and compares it to the current production version $modulemanifest = Join-Path (get-item $PSScriptRoot).Parent.FullName 'Get-PC.psd1' $Version = (Test-ModuleManifest $modulemanifest).version if ($devStage -eq "Prod") { $deployedVersion = (Test-ModuleManifest $getPCProdBuildPath).Version } elseif ($devStage -eq "Dev") { $deployedVersion = (Test-ModuleManifest $getPCDevBuildPath).Version } #lets user know when get-pc has been imported and what version they are running Write-Host "`nGet-PC Module Version $Version [$devStage] Loaded." -ForegroundColor Green if ($Version -ne $deployedVersion) { Write-Host 'New version of Get-PC is available. Please run Get-PC -Update' -ForegroundColor Yellow } Write-Host "Enter 'Help Get-PC' for available commands.`n" -ForegroundColor Green #endregion Function Get-PC { <# .Synopsis Get-PC is a custom Powershell module that contains many useful features for querying details about workstations and also performing many useful/common functions on those computers remotely. .DESCRIPTION Using get-pc hostname will query a workstation (or multiple workstations, comma separated) for information such as model, SSO client, currently logged in user, OS version, RAM, installed printers, etc… Expanded functionality can be accessed using these flags -Apps | shows the installed applications on the computer -AppDiff | shows the installed applications that are not in the standard image -Bypass | used in conjuction with remote viewer will bypass user prompt -Devices | shows connected monitors and usb devices -EventLog | pulls up errors in the event log for the last x days -Excel | exports collected data to csv and opens it with excel -Filesystem | access the file system -GPUpdate | runs a gpupdate -InstallNet35 | installs .Net 3.5 -LogOffUser | remotely logs off user -Orion | opens orion to the mac address of the pc -PCCleanup | removes temp files and inactive user profiles -PCReboot | reboots computer -PCRename | renames computer -RemoteDesktopApp | remote into computer using RDP -RequestLauncher | starts request launcher -ResetRepository | remotely resets repository -Resources | more details about system resources -SCCM | queries sccm for the computer information -SHSPrinter | pulls data about a printer using snmp -SHSPrinterweb | pulls data about a printer and opens web interface and orion -SHSUser | get data about a user from AD, can accept username or employee number -Tableview | output the results in a table -Usb | shows installed usb devices -UserProfileBackup | backups and restores user profiles -ViewerRemote | remote into the computer using RemoteViewer -Wake | attempts to wake on LAN -WinProfileRebuild | rebuilds user profiles For more detailed help please see the documentation on AppDoc .EXAMPLE Get-PC [Hostname], [Hostname], [Hostname] .EXAMPLE Get-PC [Hostname] -TableView -Apps .EXAMPLE Get-PC [Hostname] -FileSystem #> [CmdletBinding()] param ( [Parameter(ValueFromPipeline = $true)] [string[]]$ComputerName = $env:COMPUTERNAME, [Switch]$Apps, [Switch]$AppDiff, [Switch]$Bypass, [switch]$Devices, [Switch]$EventLog, [switch]$Excel, [Switch]$FileSystem, [Switch]$GPUpdate, [Switch]$HostnamesByPrinter, [switch]$InstallNet35, [switch]$Jobsprinters, [Switch]$LogOffUser, [Switch]$NextPrinterName, [switch]$Orion, [Switch]$PatchNotes, [Switch]$PCCleanup, [Switch]$PCReboot, [Switch]$PCRename, [Switch]$RemoteDesktopApp, [Switch]$RequestLauncher, [Switch]$Resources, [Switch]$ResetRepository, [Switch]$SCCM, [Switch]$SHSPrinter, [switch]$SHSPrinterWeb, [Switch]$SHSUser, [Switch]$TableView, [switch]$Update, [switch]$Usb, [Switch]$UserProfileBackup, [Switch]$ViewerRemote, [Switch]$Wake, [Switch]$WinProfileRebuild ) if (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { Write-Warning "Get-PC requires powershell to be run as administrator. Please re-launch powershell as administrator." break } <#$charA = $ComputerName.ToCharArray() if($charA -contains '*'){ if($charA -lt 4){ Write-Host "Wildcard searches need to be at least 4 characters long" -ForegroundColor Red return } Write-Host "Starting CMDB Wildcard Search..." $searchResults = Search-CMDB -hostname $ComputerName.Replace('*','') | Sort-Object -Property Hostname Write-Output $searchResults if($TableView){ $searchResults | Out-GridView -Title 'Get-PC Wildcard Search' } return } #> $getPCComputers = @() #List of computers that will get a batch query $outPutArray = @() #For use near the end of the script to output to users screen in a specified format $PCID = 1 #This is a helper variable for the progress bar if ($Jobsprinters) { #runs the printer query as a set of jobs $outPutArray = Get-PCBatchJob($ComputerName) -printers Write-Output $outPutArray } if (!$Jobsprinters) { # Stuff only run once if ($Update) { #updates get pc Update-GetPC return } $NumberofComputers = $ComputerName.Count foreach ($comp in $ComputerName) { if ($PatchNotes) { $scriptparent = (get-item $PSScriptRoot ).parent.FullName Write-Host "`n" Get-Content $scriptparent\patchnotes.txt break } #Pulls user data from AD if ($SHSUser) { $user = Get-SHSUser $comp $outPutArray += $user continue } #Asset Tag Check if ($comp.length -eq 5 -and !$SHSPrinter) { $assettag = $comp $comp = Get-AssetConversion $comp if ($null -eq $comp) { Write-Host "`n$assettag Asset Tag not in SMBIOS or CMDB" -ForegroundColor Red $props = [Ordered]@{ Hostname = "$assettag Asset Tag not in SMBIOS" Status = "" 'Current User' = "" 'Last User(s)' = "" 'IP | MAC' = "" Model = "" 'OS' = "" 'OS Build' = "" 'BIOS Ver' = "" Encryption = "" 'Free Space' = "" RAM = "" 'SSO Client' = "" 'Kiosk Role' = "" 'Citrix Ver' = "" 'Asset Tag' = "" 'Service Tag' = "" 'Last Reboot' = "" 'TPM Status' = "" 'MBAM GPO' = "" Printers = "" } $obj = New-Object -TypeName PSObject -Property $props $outPutArray += $obj continue } #Service Tag Check } elseif ($comp.length -eq 7) { if (Resolve-DnsName $comp) { #DREW SUCKS } else { $serviceTag = $comp $comp = Get-ServiceTagConversion $comp if ($null -eq $comp) { Write-Host "`n$serviceTag Service Tag not found in SCCM" -ForegroundColor Red $props = [Ordered]@{ Hostname = "$serviceTag Service Tag not found in SCCM" Status = "" 'Current User' = "" 'Last User(s)' = "" 'IP | MAC' = "" Model = "" 'OS' = "" 'OS Build' = "" 'BIOS Ver' = "" Encryption = "" 'Free Space' = "" RAM = "" 'SSO Client' = "" 'Kiosk Role' = "" 'Citrix Ver' = "" 'Asset Tag' = "" 'Service Tag' = "" 'Last Reboot' = "" 'TPM Status' = "" 'MBAM GPO' = "" Printers = "" } $obj = New-Object -TypeName PSObject -Property $props $outPutArray += $obj continue } } } #Pulls basic SNMP Data from printer $comp if ($SHSPrinter) { Write-Progress -Activity "Querying Printers" -Status "$comp ($PCID/$NumberofComputers)" -PercentComplete (($PCID / $NumberofComputers) * 100) $printer = Get-SHSPrinter $comp $outPutArray += $printer $PCID++ continue } if ($SHSPrinterWeb) { $printer = Get-SHSPrinter $comp Write-Output $printer Start-SHSPrinterWeb $printer break } #Grabs all hostnames that have the requested printer installed on it if ($HostnamesByPrinter) { $printers = HostnamesByPrinter $comp $out = @() foreach ($printer in $printers) { if ($printer -notlike '*EPIC*') { $out += $printer } } if ($TableView) { $out | Out-GridView -Title "Workstations Associated with $comp" } else { Write-Output $out } break } #Launches the request launcher script which containts landesk request template scripts if ($RequestLauncher) { Invoke-Expression \\int.samhealth.net\files\team\SHSISDesktopSolutions\Powershell\RequestLauncher\RequestLauncher.lnk break } #Generates an available printer hostname. Useful for supplying a new hostname in new printer requests if ($NextPrinterName) { Find-NextPrinterName $comp break } if ($Wake) { Invoke-Wake $comp continue } #PING HERE - All commands after here either require the computer to be online or need to know #------------------------------------------------------------------------------------------------------------------------------------------------------------------# $Connection = Test-Connection -ComputerName $comp -Count 1 Write-Progress -Activity "Connecting to computers" -Status "$comp ($PCID/$NumberofComputers)" -PercentComplete (($PCID / $NumberofComputers) * 100) if ($Connection) { $compStatus = 'Online' } else { $compStatus = 'Offline' } #grabs some basic usb info from the wmi if ($Usb) { if ($compStatus -ne 'Online') { Write-Warning "$comp is $compStatus unable to proccess command" break } Get-USB $comp break } #grabs info on attached monitors and usb devices if ($Devices) { ProgressBar -CurrentPC $comp -NumberofComputers $NumberofComputers -Percent $PCID -CurrentLocationText 'Devices' -CurrentPCNumber $PCID $PCID++ if ($compStatus -ne 'Online') { Write-Warning "$comp is $compStatus unable to proccess command" continue } $out = Get-Devices $comp if ($null -eq $out) { Write-Warning "Unable to get device info for $comp" continue } $outPutArray += $out continue } #Pulls the event log for the past x days if ($EventLog) { if ($compStatus -ne 'Online') { Write-Warning "$comp is $compStatus unable to proccess command" break } Get-PCEventLog $comp break } #Will remove selected users profile from C:\Users\ and cleans the registry of their profile if ($WinProfileRebuild) { if ($compStatus -ne 'Online') { Write-Warning "$comp is $compStatus unable to proccess command" break } Get-WinProfileRebuild $comp break } if ($ResetRepository) { if ($compStatus -ne 'Online') { Write-Warning "$comp is $compStatus unable to proccess command" break } Get-ResetRepository $comp break } #Backs up user profile to specified destination if ($UserProfileBackup) { if ($compStatus -ne 'Online') { Write-Warning "$comp is $compStatus unable to proccess command" break } Get-UserProfileBackup $comp break } #Remotely renames and restarts the computer. if ($PCRename) { if ($compStatus -ne 'Online') { Write-Warning "$comp is $compStatus unable to proccess command" break } Get-PCRename $comp break } #removes temp, cache files, and inactive user profiles if ($PCCleanup) { if ($compStatus -ne 'Online') { Write-Warning "$comp is $compStatus unable to proccess command" break } Get-PCCleanup $comp Get-PCProfileCleanup $comp break } #Will reboot the users selected PC if ($PCReboot) { if ($compStatus -ne 'Online') { Write-Warning "$comp is $compStatus unable to proccess command" break } Get-PCReboot $comp break } #Pulls brief overview of system resources if ($Resources) { if ($compStatus -ne 'Online') { Write-Warning "$comp is $compStatus unable to proccess command" continue } get-resources $comp continue } #Pulls a list of installed programs from SCCM. May not be up to date if changes were made after the last sccm scan if ($Apps) { Get-Apps $comp $TableView continue } if ($AppDiff) { Get-AppDiff $comp $TableView continue } if ($GPUpdate) { if ($compStatus -ne 'Online') { Write-Warning "$comp is $compStatus unable to proccess command" break } Get-GPUpdate $comp break } #Will not notify the user that another user is about to remote onto their PC if ($Bypass) { if ($compStatus -ne 'Online') { Write-Warning "$comp is $compStatus unable to proccess command" break } Get-Bypass $comp } #Runs Remote Viewer, Thick Client Only if ($ViewerRemote) { if ($compStatus -ne 'Online') { Write-Warning "$comp is $compStatus unable to proccess command" break } Get-ViewerRemote $comp continue } #Runs Remote Desktop Connection Application if ($RemoteDesktopApp) { if ($compStatus -ne 'Online') { Write-Warning "$comp is $compStatus unable to proccess command" break } Get-RemoteDesktopApp $comp break } #Same as C$ into a workstation if ($FileSystem) { if ($compStatus -ne 'Online') { Write-Warning "$comp is $compStatus unable to proccess command" continue } Get-FileSystem $comp continue } #Will log off the current logged in user for the designated PC #Adapted from Josh Gobens Logoff Script if ($LogOffUser) { if ($compStatus -ne 'Online') { Write-Warning "$comp is $compStatus unable to proccess command" break } Get-LogOffUser $comp break } if ($InstallNet35) { Get-InstallNet35 $comp continue } #Checks if there is a WinRM service error #TODO Re-evaluate where we want the WSNetwork test #$WSNetworkTest = Test-WSMan -ComputerName $comp #-or ($null -eq $WSNetworkTest) #checks to see if the computer is in AD or the disabled computers OU and warns the user if (get-module -ListAvailable -Name 'ActiveDirectory') { Write-Progress -Activity "Looking up computer in AD" -Status "$comp ($PCID/$NumberofComputers)" -PercentComplete (($PCID / $NumberofComputers) * 100) try { $adTest = ((Get-ADComputer $comp).DistinguishedName -match "Disabled Computers") } catch { $adTest = $true } if ($adTest) { Write-Warning "$comp is either disabled or off the domain" } } #Direct SCCM Queries if ( $SCCM ) { $result = Get-SCCMQuery $comp $NumberofComputers $PCID $PCID++ $outPutArray += $result } else { #Checks if local computer if ($comp -eq $env:COMPUTERNAME) { $result = Get-PCLocal $comp $NumberofComputers $PCID #$PCID++ #$result = get-PCremoteCleaned $comp $Connection $NumberofComputers $PCID $outPutArray += $result #$getPCComputers += $comp } else { #$result = Get-PCRemote $comp $NumberofComputers $PCID #$result = get-PCremoteCleaned $comp $Connection $NumberofComputers $PCID #$PCID++ #$outPutArray += $result #Write-Output $result $getPCComputers += $comp } } if ($Orion) { break } } } #This is the get-pc of get-pc. It collects all the data from the computers and puts it in an array to be outputed $outPutArray += Get-PCBatchInvoke($getPCComputers) if ($Orion) { $mac = $outPutArray[0].'IP | MAC' -split " " if ($mac) { $mac = $mac[2] -split "," $mac = $mac[0] Write-Host "Launching Orion page to $mac" Start-Process "https://shsorion/Orion/UDT/EndpointDetails.aspx?NetObject=UE-MAC:VAL=$mac" } else { Write-Host "Unable to validate MAC" } } Write-Output $outPutArray #Creats an out grid view of all the data collected if ($TableView) { $outPutArray | Out-GridView -Title "Get-PC Grid" } #Takes the outputed data and exports it to a csv in the user's temp folder. Then opens that file with default csv viewer. It should be excel for most users if ($Excel) { ExportToExcel $outPutArray } } Function ProgressBar($Percent, $CurrentPC, $CurrentLocationText, $NumberofComputers, $CurrentPCNumber) { Write-Progress -Activity "Scanning PC $CurrentPC ($CurrentPCNumber/$NumberofComputers)" -Status "Querying: $CurrentLocationText" -PercentComplete (($Percent / 18) * 100) }