Get-PC/Public/Get-PC.ps1

683 lines
23 KiB
PowerShell
Raw Normal View History

2024-06-11 18:27:55 +00:00
#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
2024-09-04 22:55:37 +00:00
$ErrorActionPreference = 'SilentlyContinue'
2024-06-11 18:27:55 +00:00
#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
}
$getPCWrappedPath = '\\int.samhealth.net\files\TEAM\SHSISDesktopSolutions\Powershell\Get-PC_Update_2023\Get-PC-Wrapped\backlog.txt'
2024-06-11 18:27:55 +00:00
#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
-ClearCCMCache | clears CCM cache, may fix software center
-CMDB | only queries CMDB for info
2024-06-11 18:27:55 +00:00
-Devices | shows connected monitors and usb devices
2024-09-12 23:46:24 +00:00
-DevicesUnplugged | shows unplugged devices like scanners and printers
2024-06-11 18:27:55 +00:00
-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
-Monitor | monitors computers for changes in status
-NextPrinterName | generates next open printer name
2024-06-11 18:27:55 +00:00
-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
-ResetRepository | remotely resets repository
-Resources | more details about system resources
-PrinterPurge | removes printer from all online computers
2024-06-11 18:27:55 +00:00
-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
-UninstallProgram | remotely uninstall a program from a pc
2024-06-11 18:27:55 +00:00
-Usb | shows installed usb devices
-UserProfileBackup | backups and restores user profiles
-ViewerRemote | remote into the computer using RemoteViewer
-Wake | attempts to wake on LAN
2024-06-11 18:27:55 +00:00
-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]$ClearCCMCache,
[Switch]$CMDB,
2024-06-11 18:27:55 +00:00
[switch]$Devices,
2024-09-12 23:46:24 +00:00
[switch]$DevicesUnplugged,
2024-06-11 18:27:55 +00:00
[Switch]$EventLog,
[switch]$Excel,
[Switch]$FileSystem,
[Switch]$GPUpdate,
[Switch]$HostnamesByPrinter,
[switch]$InstallNet35,
[switch]$Jobsprinters,
[Switch]$LogOffUser,
[Switch]$Monitor,
2024-06-11 18:27:55 +00:00
[Switch]$NextPrinterName,
[switch]$Orion,
[Switch]$PatchNotes,
[Switch]$PCCleanup,
[Switch]$PCReboot,
[Switch]$PCRename,
[Switch]$Quiet,
2024-06-11 18:27:55 +00:00
[Switch]$RemoteDesktopApp,
[Switch]$ResetRepository,
[Switch]$Resources,
[Switch]$PrinterPurge,
2024-06-11 18:27:55 +00:00
[Switch]$SCCM,
[Switch]$SHSPrinter,
[switch]$SHSPrinterWeb,
[Switch]$SHSUser,
[Switch]$TableView,
[Switch]$UninstallProgram,
2024-06-11 18:27:55 +00:00
[switch]$Update,
[switch]$Usb,
[Switch]$UserProfileBackup,
[Switch]$ViewerRemote,
[Switch]$Wake,
2024-06-11 18:27:55 +00:00
[Switch]$WinProfileRebuild
)
#Data collection for Get-PC Wrapped TM
$invokeData = @{
Hostname = $env:COMPUTERNAME
Username = $env:USERNAME
Datetime = Get-Date -Format 'yyyy-MM-ddThh:mm:ss.fffffff'
Parameters = $MyInvocation.BoundParameters
}
Add-Content -Path $getPCWrappedPath -Value $(ConvertTo-Json -Compress $invokeData)
## Define which Spark Record Properties are Returned
$Spark_Property_Return = @(
"Name",
"ivnt_assetfulltype",
"ivnt_location",
"SHS_LocationDetails",
"AssetTag",
"SerialNumber",
"Owner",
"Status"
)
2024-06-11 18:27:55 +00:00
<#
2024-06-11 18:27:55 +00:00
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
}
#>
2024-06-11 18:27:55 +00:00
# Stuff only run once
if ($Update) {
#updates get pc
Update-GetPC
return
}
2024-08-02 19:03:04 +00:00
if ($PatchNotes) {
$scriptparent = (get-item $PSScriptRoot ).parent.FullName
Write-Host "`n"
Get-Content $scriptparent\patchnotes.txt
break
2024-06-11 18:27:55 +00:00
}
if ($Jobsprinters) {
#runs the printer query as a set of jobs
$outPutArray = Get-PCBatchJob($ComputerName) -printers
Write-Output $outPutArray
return
}
if($locationSearch){
Write-Host 'Please enter a partial location like a room number.'
$searchInput = Read-Host 'Location'
Write-Host "Searching CMDB for $searchInput ..."
<# $ComputerName
if($ComputerName.count -gt 1){
Write-Host 'Can only search a single location at a time' -ForegroundColor Yellow
return
} #>
if($searchInput.ToCharArray().Length -lt 3){
Write-Host 'Location searches much contain more than 2 characters' -ForegroundColor Yellow
return
}
$searchResults = Search-CMDB -Location $searchInput | Sort-Object -Property Hostname
2024-09-11 21:02:15 +00:00
if($null -eq $searchResults){
Write-Host 'No results for given search' -ForegroundColor Yellow
return
}
Write-Output $searchResults
return
}
$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
$output = @()
foreach ($comp in $ComputerName) {
$searchResults = Find-ISMBO -BusinessObject "cis" -SearchQuery $comp | Sort-Object -Property Name
$output += Write-Output $searchResults | Select-Object $Spark_Property_Return
}
#$searchResults = Find-ISMBO -BusinessObject "cis" -SearchQuery $ComputerName.Replace('*','') | Sort-Object -Property Name
if($TableView){
$output | Out-GridView -Title 'Get-PC Wildcard Search'
}
return $output
}
2024-06-11 18:27:55 +00:00
$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
$NumberofComputers = $ComputerName.Count
foreach ($comp in $ComputerName) {
#Pulls user data from AD
if ($SHSUser) {
$user = Get-SHSUser $comp
$outPutArray += $user
continue
2024-06-11 18:27:55 +00:00
}
$comp,$msg = Get-Hostname $comp
if ($msg -and -not $SHSPrinter) {
Write-Host "`n$msg" -ForegroundColor Red
$props = [Ordered]@{
Hostname = "$msg"
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
2024-06-11 18:27:55 +00:00
$outPutArray += $obj
2024-06-11 18:27:55 +00:00
continue
}
2024-06-11 18:27:55 +00:00
if ($CMDB) {
$outputArray += Get-CMDBFallback $comp
continue
}
#DREW SUCKS
2024-06-11 18:27:55 +00:00
#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
2024-06-11 18:27:55 +00:00
}
}
if ($TableView) {
$out | Out-GridView -Title "Workstations Associated with $comp"
}
else {
Write-Output $out
}
continue
}
2024-06-11 18:27:55 +00:00
if ($PrinterPurge) {
Invoke-PrinterPurge $comp
continue
}
#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"
2024-06-11 18:27:55 +00:00
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++
2024-06-11 18:27:55 +00:00
if ($compStatus -ne 'Online') {
Write-Warning "$comp is $compStatus skipping monitor query"
2024-06-11 18:27:55 +00:00
}
$out = Get-Devices $comp $compStatus
if ($null -eq $out) {
Write-Warning "Unable to get device info for $comp"
continue
}
2024-06-11 18:27:55 +00:00
$outPutArray += $out
continue
}
2024-09-12 23:46:24 +00:00
if ($DevicesUnplugged) {
if ($compStatus -ne 'Online') {
Write-Warning "$comp is $compStatus unable to query unplugged devices"
continue
}
$outPutArray += Get-DevicesUnplugged $comp
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"
2024-06-11 18:27:55 +00:00
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"
2024-06-11 18:27:55 +00:00
break
}
Get-WinProfileRebuild $comp
break
}
if ($ResetRepository) {
2024-06-11 18:27:55 +00:00
if ($compStatus -ne 'Online') {
Write-Warning "$comp is $compStatus unable to proccess command"
continue
2024-06-11 18:27:55 +00:00
}
Get-ResetRepository $comp
continue
}
#Backs up user profile to specified destination
if ($UserProfileBackup) {
if ($compStatus -ne 'Online') {
Write-Warning "$comp is $compStatus unable to proccess command"
2024-06-11 18:27:55 +00:00
break
}
Get-UserProfileBackup $comp
break
}
#Remotely renames and restarts the computer.
if ($PCRename) {
2024-06-11 18:27:55 +00:00
if ($compStatus -ne 'Online') {
Write-Warning "$comp is $compStatus unable to proccess command"
2024-06-11 18:27:55 +00:00
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"
2024-06-11 18:27:55 +00:00
break
}
Get-PCCleanup $comp
Get-PCProfileCleanup $comp
break
}
2024-06-11 18:27:55 +00:00
#Will reboot the users selected PC
if ($PCReboot) {
if ($compStatus -ne 'Online') {
Write-Warning "$comp is $compStatus unable to proccess command"
2024-06-11 18:27:55 +00:00
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
2024-06-11 18:27:55 +00:00
}
get-resources $comp
continue
}
#Pulls a list of installed programs from SCCM and Get-Package
if ($Apps) {
Get-Apps $comp $TableView
continue
}
2024-06-11 18:27:55 +00:00
if ($AppDiff) {
Get-AppDiff $comp $TableView
continue
}
if ($UninstallProgram) {
Invoke-UninstallProgram $comp
break
}
2024-06-11 18:27:55 +00:00
if ($GPUpdate) {
if ($compStatus -ne 'Online') {
Write-Warning "$comp is $compStatus unable to proccess command"
continue
2024-06-11 18:27:55 +00:00
}
Get-GPUpdate $comp
continue
}
#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
2024-06-11 18:27:55 +00:00
}
Get-Bypass $comp
}
2024-06-11 18:27:55 +00:00
#Removes any indicator that another user is remoted onto their PC (like the green bar)
if ($Quiet) {
2024-06-11 18:27:55 +00:00
if ($compStatus -ne 'Online') {
Write-Warning "$comp is $compStatus unable to proccess command"
break
2024-06-11 18:27:55 +00:00
}
Invoke-Quiet $comp
}
2024-06-11 18:27:55 +00:00
#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
break
}
#Runs Remote Desktop Connection Application
if ($RemoteDesktopApp) {
if ($compStatus -ne 'Online') {
Write-Warning "$comp is $compStatus unable to proccess command"
2024-06-11 18:27:55 +00:00
break
}
Get-RemoteDesktopApp $comp
break
}
#Same as C$ into a workstation
if ($FileSystem) {
2024-06-11 18:27:55 +00:00
if ($compStatus -ne 'Online') {
Write-Warning "$comp is $compStatus unable to proccess command"
continue
2024-06-11 18:27:55 +00:00
}
Get-FileSystem $comp
continue
}
if ($ClearCCMCache) {
if ($compStatus -ne 'Online') {
Write-Warning "$comp is $compStatus unable to proccess command"
continue
}
Invoke-ClearCCMCache $comp
continue
}
#Will log off the current logged in user for the designated PC
#Adapted from Josh Gobens Logoff Script
if ($LogOffUser) {
2024-06-11 18:27:55 +00:00
if ($compStatus -ne 'Online') {
Write-Warning "$comp is $compStatus unable to proccess command"
2024-06-11 18:27:55 +00:00
break
}
Get-LogOffUser $comp
break
}
2024-06-11 18:27:55 +00:00
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 }
2024-06-11 18:27:55 +00:00
if ($adTest) {
Write-Warning "$comp is either disabled or off the domain"
2024-06-11 18:27:55 +00:00
}
Write-Progress -Activity "Looking up computer in AD" -Completed
}
#Direct SCCM Queries
if ( $SCCM ) {
$result = Get-SCCMQuery $comp $NumberofComputers $PCID
$PCID++
$outPutArray += $result
}
else {
2024-06-11 18:27:55 +00:00
#Checks if local computer
if ($comp -eq $env:COMPUTERNAME) {
$result = Get-PCLocal $comp $NumberofComputers $PCID
#$PCID++
#$result = get-PCremoteCleaned $comp $Connection $NumberofComputers $PCID
2024-06-11 18:27:55 +00:00
$outPutArray += $result
#$getPCComputers += $comp
2024-06-11 18:27:55 +00:00
}
else {
#$result = Get-PCRemote $comp $NumberofComputers $PCID
#$result = get-PCremoteCleaned $comp $Connection $NumberofComputers $PCID
#$PCID++
#$outPutArray += $result
#Write-Output $result
$getPCComputers += $comp
2024-06-11 18:27:55 +00:00
}
}
if ($Orion) {
break
2024-06-11 18:27:55 +00:00
}
}
# Monitor list of PCs for change in online status or
if ($Monitor) {
Invoke-PCMonitor $getPCComputers
return
}
2024-06-11 18:27:55 +00:00
#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 / 29) * 100)
2024-06-11 18:27:55 +00:00
}