Get-PC/Private/BatchInvokes.ps1
Zachary Gorman 2c4ce1bf3a Utilized Sean's ITSM interface instead.
This interface is more standardized and robust, and utilizes an api key
instead of SID which is more seamless for the end user.
2024-08-07 11:41:54 -07:00

453 lines
19 KiB
PowerShell

function Get-PCBatchInvoke {
[CmdletBinding()]
param (
[Parameter()]
[string[]]
$Computers
)
$Tenant = (Connect-ISM)[1]
$Headers = (Connect-ISM)[0]
#Region Script Block
$sblock = {
Write-Progress -Activity "Retrieving data from online computers" -Status $Env:COMPUTERNAME -PercentComplete 10
try {$win32_networkadapterconfiguration = Get-CimInstance -Class win32_networkadapterconfiguration} catch {$win32_networkadapterconfiguration = $null} #| MAC Address,
try {$win32_LogicalDisk = Get-CimInstance -ClassName Win32_LogicalDisk -Filter "DriveType=3" } catch {$win32_LogicalDisk = $null} #| Diskspace,
try {$win32_SystemEnclosure = Get-CimInstance -ClassName Win32_SystemEnclosure} catch {$win32_SystemEnclosure = $null} #| Asset Tag
Write-Progress -Activity "Retrieving data from online computers" -Status $Env:COMPUTERNAME -PercentComplete 20
try {$bitlocker = manage-bde -status C:} catch {$bitlocker = $null} # | Bitlocker Status
try {$PCInfo = get-computerinfo} catch {$PCInfo = $null}
Write-Progress -Activity "Retrieving data from online computers" -Status $Env:COMPUTERNAME -PercentComplete 30
try {$physicalDisk = Get-PhysicalDisk} catch {$physicalDisk = $null} # | Disk Type
try {$win32_printer = (Get-CimInstance -ClassName win32_printer | Where-Object {$_.PortName -ne 'PORTPROMPT:' -and $_.PortName -ne 'nul:' -and $_.PortName -ne 'SHRFAX:'} | Select-Object -ExpandProperty Name) -join ' || ' }
catch{ $win32_printer = $null} # | Printers
try {$imprivataRegEntry = Get-ItemProperty -Path Registry::HKEY_LOCAL_MACHINE\SOFTWARE\SSOProvider\ISXAgent} catch {$imprivataRegEntry = $null}
Write-Progress -Activity "Retrieving data from online computers" -Status $Env:COMPUTERNAME -PercentComplete 40
try {$kioskRegEntry = Get-ItemProperty -Path Registry::HKEY_LOCAL_MACHINE\SOFTWARE\SHSCustom} catch {$kioskRegEntry = $null}
try {$win32_tpm = Get-CimInstance -Namespace root\cimv2\security\microsofttpm -Class win32_tpm} catch{$win32_tpm = $null} # | TPM
$gpoPath = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE\MDOPBitLockerManagement"
$gpoValue = Get-ItemPropertyValue -Path $gpoPath -Name "KeyRecoveryServiceEndPoint"
Switch($GpoValue -eq "https://shsmbam1.int.samhealth.net/MBAMRecoveryAndHardwareService/CoreService.svc")
{
$true {$gpoStatus = "GPO Applied"}
$false {$gpoStatus = "GPO Not Applied (Check if system is member of group MBAM_Default on ADUC"}
Default {$gpoStatus = "Error...GPOTEST Line PCRemote Line 276"}
}
Write-Progress -Activity "Retrieving data from online computers" -Status $Env:COMPUTERNAME -PercentComplete 50
$CitrixViewer = "C:\Program Files (X86)\Citrix\ICA Client\CDViewer.exe"
#$LastUser = Get-ChildItem -Path C:\Users -Directory -Force -Exclude Public,Default,'Default User','All Users' | Sort-Object -Property LastWriteTime -Descending | Select-Object -First 3 # | Last Users
try {$CPU = (Get-CimInstance -ClassName Win32_processor ).Name } catch {$CPU = $null}
#MAC Address
$MAC = ($win32_networkadapterconfiguration | Where-Object {$_.IpEnabled -Match "True"} | Select-Object -Expand macaddress) -join ","
#IP
$ip = ($win32_networkadapterconfiguration | Where-Object {$_.IpEnabled -Match "True"} | Select-Object -Expand IPAddress)
if($ip -is [array]){
$ip = $ip[0]
}
#Adapter
$adapter = ($win32_networkadapterconfiguration | Where-Object {$_.IpEnabled -Match "True"} | Select-Object -Expand Description)
<#
if($adapter -is [array]){
$adapter = $adapter[0]
}
#>
#UserName
$Username = $PCInfo.CSUserName
if($null -eq $Username){
$Username = (Invoke-Command -SessionOption (New-PSSessionOption -NoMachineProfile) -ScriptBlock {Get-Process Explorer -IncludeUsername | Where-Object { $_.Username -notlike "*SYSTEM" }} ).Username
if($null -ne $Username){
$Username = "$Username (RDP/Inactive)"
}
else{
$Username = '**None**'
}
}
#Collecting most recent users from the registry
$lastuser = @()
$profiles = Get-CimInstance -Class Win32_UserProfile
$profiles | Where-Object {$_.SID.length -gt 10} | Foreach-Object {
$sid = $_.SID
$prop = Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\$sid\"
if($prop.LocalProfileUnLoadTimeHigh -and $prop.LocalProfileUnLoadTimeLow){
$a = '{0:x}' -f $prop.LocalProfileUnLoadTimeHigh
$b = '{0:x}' -f $prop.LocalProfileUnLoadTimeLow
$dec = [bigint]::Parse("$a$b",'AllowHexSpecifier')
$time = w32tm /ntte $dec
$lastTime = [datetime]($time -split ' - ')[1]
}
else{
$lastTime = "Unknown"
}
$obj = [PSCustomObject]@{
Name = ($_.LocalPath -split 'C:\\Users\\')[1]
LocalPath = $_.LocalPath
LastLoginTime = $lastTime
}
$lastuser += $obj
}
$lastuser = $lastuser | Where-Object LastLoginTime -ne 'Unknown' | Sort-Object LastLoginTime -Descending
#Last User
if($lastUser.Count -gt 1){
$lastUser1 = ($lastUser[0].Name + " (" + $lastUser[0].LastLoginTime + ")")
$lastUser2 = ($lastUser[1].Name + " (" + $lastUser[1].LastLoginTime + ")")
$lastUser3 = ($lastUser[2].Name + " (" + $lastUser[2].LastLoginTime + ")")
$TotalLastUsers = "$lastUser1 $lastUser2 $lastUser3"
}else{
$TotalLastUsers = $lastUser.Name + " (" + $lastUser.LastLoginTime + ")"
}
#ComputerModel
$Model = $PCInfo.CsModel
#RAM
$totalram = $PCInfo.CsTotalPhysicalMemory
$totalram = [math]::Round(($totalram / 1GB))
$ram = "$totalram GB"
#Drive Type
$DriveType = $physicalDisk.MediaType
Write-Progress -Activity "Retrieving data from online computers" -Status $Env:COMPUTERNAME -PercentComplete 60
#Free Harddrive Space
$CompFreeSpace = @([math]::Round($win32_LogicalDisk.FreeSpace / 1gb,2),[math]::Round($win32_LogicalDisk.Size / 1gb,2))
$free = $compFreeSpace[0]
$max = $compfreeSpace[1]
$freespace = "$free GB / $max GB"
#Service Tag
#$serviceTag = $win32_bios.SerialNumber
$serviceTag = $PCInfo.BiosSeralNumber
#BIOS
#$biosVersion = $win32_bios.SMBIOSBIOSVersion
$biosVersion = $PCInfo.BiosName
#Last Reboot
$lastbootTime = $PCInfo.OsLastBootUpTime
#Asset Tag
$assetTag = $win32_SystemEnclosure.SMBiosAssetTag
#Bitlocker Status
$PercentageEncrypted = (($bitlocker | Select-String "Percentage Encrypted") -split ': ')[1]
[int]$IntPercentageEncrypted = $PercentageEncrypted.Substring(0,4)
$EncryptionStatus = $null
If($bitlocker -like '*error*')
{
$EncryptionStatus = 'BitLocker - Error - Please investigate'
}
Elseif($IntPercentageEncrypted -eq 100)
{
$EncryptionStatus = "BitLocker - Encrypted ($PercentageEncrypted)"
}
ElseIf($IntPercentageEncrypted -gt 1)
{
$EncryptionStatus = "BitLocker - Encrypting ($PercentageEncrypted)"
}
Else
{
$EncryptionStatus = "BitLocker - Decrypted ($PercentageEncrypted)"
}
#OS
$os = $PCInfo.OSName + " (" + $PCInfo.OSArchitecture + ")"
#OS Build
$osVer = $PCInfo.WindowsVersion
if($osVer -gt 2004){
$osVer = (Get-ItemProperty -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion").DisplayVersion
}
$osBuild = $PCInfo.OSBuildNumber
$osBuild = "Vers $osVer | Build #$osBuild"
Write-Progress -Activity "Retrieving data from online computers" -Status $Env:COMPUTERNAME -PercentComplete 70
#Printers
$printers = $win32_printer# ($win32_printer | Where-Object {$_.PortName -ne 'PORTPROMPT:' -and $_.PortName -ne 'nul:' -and $_.PortName -ne 'SHRFAX:'} | Select-Object -ExpandProperty Name) -join ' || '
if(!$printers){
$printers = "No Local/Networked Printer (Check Printer Mappings)"
}
#Imprivata
$ImprivataType = $imprivataRegEntry | Select-Object -ExpandProperty Type
if(!$imprivataType){
$ImprivataType = "Not Installed"
}
else{
Switch($ImprivataType){
1 {
$ImprivataType = $imprivataRegEntry | Select-Object -ExpandProperty FUS_Enabled
Switch($ImprivataType){
0 {$ImprivataType = "SUD"}
1 {$ImprivataType = "MUD"}
}
}
2 {$ImprivataType = "Kiosk"}
Default {$ImprivataType = "Not Installed"}
}
}
$kioskRole = try {$kioskRegEntry | Select-Object -ExpandProperty KioskRole} catch{ $null }
if (!$kioskRole) { $kioskRole = "None"}
#TPM
if($win32_tpm){
$tpmVersion = " | Vers " + $win32_tpm.ManufacturerVersionFull20
$tpmStatus = "On"
if($win32_tpm.IsActivated_InitialValue){
$tpmStatus += ", Activated"
}
else{
$tpmStatus += ", Not Activated"
}
if($win32_tpm.IsEnabled_InitialValue){
$tpmStatus += ", Enabled"
}
else {
$tpmStatus += ", Disabled"
}
if($win32_tpm.IsOwned_InitialValue){
$tpmStatus += ", Owned"
}
else{
$tpmStatus += ", Not Owned"
}
$tpmStatus += $tpmVersion
}
else {
$tpmStatus = "Off"
}
Write-Progress -Activity "Retrieving data from online computers" -Status $Env:COMPUTERNAME -PercentComplete 80
#Citrix Version
if( !(Test-path $CitrixViewer)){
$CitrixVersion = "Not Installed"
}
else{
#Checks this default install path
$CitrixVersion = Get-Command $citrixViewer | select-object -ExpandProperty Version #Grabs Citrix version number
}
#Chassis Type
Switch -Wildcard($Model) {
"Optiplex*" {
Switch -Wildcard($CPU)
{
"Intel(R) Core(TM) i5-9500 CPU*" {$chassisType = "SFF"} #5070
"Intel(R) Core(TM) i5-6500 CPU*" {$chassisType = "SFF"} #7040
"Intel(R) Core(TM) i5-6500T*" {$chassisType = "Micro"} #7040
"Intel(R) Core(TM) i7-6700 CPU*" {$chassisType = "SFF"} #7040
"Intel(R) Core(TM) i7-6700T*" {$chassisType = "Micro"} #7040
"Intel(R) Core(TM) i5-10500T*" {$chassisType = "Micro"} #5080
"Intel(R) Core(TM) i5-9500T*" {$chassisType = "Micro"} #5070
"Intel(R) Core(TM) i5-8500 CPU*" {$chassisType = "SFF"} #5060
"Intel(R) Core(TM) i5-8500T*" {$chassisType = "Micro"} #5060
"Intel(R) Core(TM) i5-7500*" {$chassisType = "SFF"} #5050
"Intel(R) Core(TM) i5-4670 CPU*" {$chassisType = "SFF"} #9020
"Intel(R) Core(TM) i5-4590 CPU*" {$chassisType = "SFF"} #9020
"Intel(R) Core(TM) i5-4590T CPU*" {$chassisType = "Micro"} #9020M
"Intel(R) Core(TM) i5-4690 CPU*" {$chassisType = "SFF"} #9020
"Intel(R) Core(TM) i5-3550 CPU*" {$chassisType = "SFF"} #9010
"Intel(R) Core(TM) i5-2400 CPU*" {$chassisType = "SFF"} #990
Default {$chassisType = "Optiplex - Chassis Type - Unknown"}
}
}
"Latitude*" {
$chassisType = "Laptop"
}
"Precision*"{
$chassisType = "Laptop"
}
"M24*" {
$chassisType = "Anesthesia Cart"
}
"Medix*"{
$chassisType = "Anesthesia Cart"
}
Default {$chassisType = "Unknown Model/Chassis"}
}
$uri = "${using:Tenant}/api/odata/businessobject/cis`?`$filter=Name eq '$ENV:COMPUTERNAME'&`$top=1&`$skip=0"
try {
$Query = Invoke-RestMethod -Method GET -uri $uri -headers ${using:Headers}
} catch {
Write-Host $_.Exception.Message
}
$cmdbData = $Query.Value
$LocationConstructors = @(
"SHS_AssetLocality",
"ivnt_Location",
"SHS_Floor",
"SHS_Department",
"SHS_LocationDetails"
)
$LocationData = Foreach($Loc in $LocationConstructors){
if ($Loc -eq 'SHS_Floor'){
$(if ($cmdbData.$Loc -match '-'){$cmdbData.$Loc.split('-')[-1] + " Floor"} else{$cmdbData.$Loc})
} elseif (![string]::IsNullOrEmpty($cmdbData.$Loc)){
$cmdbData.$Loc
}
}
$LocationData = $LocationData -join ' | '
Write-Progress -Activity "Retrieving data from online computers" -Status $Env:COMPUTERNAME -PercentComplete 90
#Output
# $i++ | ProgressBar $i $comp 'Generating Output' $NumberofComputers $PCID
$obj = New-Object -TypeName PSObject
$obj | Add-Member -MemberType NoteProperty -Name 'Hostname' -Value $Env:COMPUTERNAME
$obj | Add-Member -MemberType NoteProperty -Name 'Status' -Value "Online"
$obj | Add-Member -MemberType NoteProperty -Name 'Current User' -Value "$userName"
$obj | Add-Member -MemberType NoteProperty -Name 'Last User(s)' -Value "$TotalLastUsers"
$obj | Add-Member -MemberType NoteProperty -Name 'IP | MAC' -Value "$ip | $mac"
$obj | Add-Member -MemberType NoteProperty -Name 'Adapter' -Value "$adapter"
$obj | Add-Member -MemberType NoteProperty -Name 'Model' -Value "$Model ($chassisType)"
$obj | Add-Member -MemberType NoteProperty -Name 'OS' -Value $os
$obj | Add-Member -MemberType NoteProperty -Name 'OS Build' -Value $osBuild
$obj | Add-Member -MemberType NoteProperty -Name 'BIOS Ver' -Value "$biosVersion"
$obj | Add-Member -MemberType NoteProperty -Name 'Encryption' -Value "$EncryptionStatus"
$obj | Add-Member -MemberType NoteProperty -Name 'Free Space' -Value "$freespace | $driveType"
$obj | Add-Member -MemberType NoteProperty -Name 'RAM' -Value "$ram"
$obj | Add-Member -MemberType NoteProperty -Name 'SSO Client' -Value "$imprivataType"
$obj | Add-Member -MemberType NoteProperty -Name 'Kiosk Role' -Value "$kioskRole"
$obj | Add-Member -MemberType NoteProperty -Name 'Citrix Ver' -Value "$citrixVersion"
$obj | Add-Member -MemberType NoteProperty -Name 'Asset Tag' -Value "$assetTag"
$obj | Add-Member -MemberType NoteProperty -Name 'Service Tag' -Value "$serviceTag"
$obj | Add-Member -MemberType NoteProperty -Name 'Last Reboot' -Value "$lastbootTime"
$obj | Add-Member -MemberType NoteProperty -Name 'TPM Status' -Value "$tpmStatus"
$obj | Add-Member -MemberType NoteProperty -Name 'MBAM GPO' -Value "$gpostatus"
$obj | Add-Member -MemberType NoteProperty -Name 'Printers' -Value "$printers"
$obj | Add-Member -MemberType NoteProperty -Name 'CMDB Location' -Value "$LocationData"
if($cmdbData.SHS_IsException -eq 'True'){
Write-host "***NOTICE: $ENV:COMPUTERNAME is a Device Exception computer. Please check CMDB/Asset Mgmt prior to supporting this workstation. ***" -BackgroundColor Black -ForegroundColor Yellow
$obj | Add-Member -MemberType NoteProperty -Name 'DEL Owner' -Value $cmdbData.SHS_ExceptionContact
$obj | Add-Member -MemberType NoteProperty -Name 'DEL Vendor PC' -Value $cmdbData.SHS_IsVendorPC
$obj | Add-Member -MemberType NoteProperty -Name 'DEL Description' -Value $cmdbData.SHS_ExceptionNotes
}
return $obj
}
#endregion
$OnlineComputers = @()
$OfflineComputers = @()
$output = @()
$itemIndex = 0
foreach($comp in $Computers){
$itemIndex++
BatchInvokesProgressBar -item $comp -currentItemIndex $itemIndex -TotalItems $Computers.Count -stage 1
$Connection = Test-Connection -ComputerName $comp -Count 1
if($Connection){
$OnlineComputers += $comp
}
else{
$OfflineComputers += $comp
}
}
BatchInvokesProgressBar -stage 2
$invokeJob = Invoke-Command -ScriptBlock $sblock -ComputerName $OnlineComputers -SessionOption (New-PSSessionOption -NoMachineProfile -OpenTimeout 45000) -AsJob
$offlineJobs = @()
if($OfflineComputers.count -gt 0){
foreach($computer in $OfflineComputers){
$offlineJobs += Start-Job -ScriptBlock ${function:Get-SCCMQueryBlock} -ArgumentList $computer
}
}
BatchInvokesProgressBar -stage 3
$output += $invokeJob | Receive-Job -Wait -AutoRemoveJob | Select-Object * -ExcludeProperty RunspaceId, PSComputerName, PSShowComputerName, PSSourceJobInstanceId
$output += $offlineJobs | Receive-Job -Wait -AutoRemoveJob | Select-Object * -ExcludeProperty RunspaceId, PSComputerName, PSShowComputerName, PSSourceJobInstanceId
$itemIndex = 0
$contactedhosts = $output.Hostname
BatchInvokesProgressBar -stage 4
$missedhosts = $OnlineComputers | Where-Object -FilterScript {$_ -notin $contactedhosts}
$missedJobs = @()
if($missedhosts.count -gt 0){
foreach($computer in $missedhosts){
$missedJobs += Start-Job -ScriptBlock ${function:Get-SCCMQueryBlock} -ArgumentList $computer
}
}
$output += $missedJobs | Receive-Job -Wait -AutoRemoveJob | Select-Object * -ExcludeProperty RunspaceId, PSComputerName, PSShowComputerName, PSSourceJobInstanceId
return $output
}
Function Get-CMDBLocation {
[CmdletBinding()]
param (
[Parameter()]
$cmdb
)
if($null -eq $cmdb){
$location = "*CMDB Mismatch - check CMDB*"
return $location
}
if($cmdb.values._SHSCalcLocationString.length -gt $cmdb.values._SHSLocation3.length){
$location = $cmdb.values._SHSCalcLocationString
}
else{
$location = $cmdb.values._SHSLocation3
}
if($null -eq $location -or '' -eq $location){
$location = "*No location data - Please update CMDB*"
}
return $location
}
function BatchInvokesProgressBar {
param (
$item,
$currentItemIndex,
$TotalItems,
$stage
)
switch ($stage) {
1 { Write-Progress -Activity "Connecting to computers" -Status "$item ($currentItemIndex/$TotalItems)" -PercentComplete (($currentItemIndex/$TotalItems) * 100)}
2 { Write-Progress -Activity "Spinning up jobs" -PercentComplete ((20/100) * 100)}
3 { Write-Progress -Activity "Awaiting Jobs" -PercentComplete ((60/100)*100)}
4 { Write-Progress -Activity "Querying SCCM for missed computers" -PercentComplete ((75/100) * 100)}
Default {}
}
}