From 4c7146890a012217316f7ee20010d7c5af389dbd Mon Sep 17 00:00:00 2001 From: Zachary Gorman Date: Tue, 25 Jun 2024 10:14:41 -0700 Subject: [PATCH 1/4] Created WatchDog class in PCMonitor to more easily track computer status --- Public/Get-PC.ps1 | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Public/Get-PC.ps1 b/Public/Get-PC.ps1 index 2420214..1e83b74 100644 --- a/Public/Get-PC.ps1 +++ b/Public/Get-PC.ps1 @@ -93,6 +93,7 @@ Function Get-PC { [switch]$InstallNet35, [switch]$Jobsprinters, [Switch]$LogOffUser, + [Switch]$Monitor, [Switch]$NextPrinterName, [switch]$Orion, [Switch]$PatchNotes, @@ -529,7 +530,7 @@ Function Get-PC { 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 @@ -580,6 +581,12 @@ Function Get-PC { } } + + # Monitor list of PCs for change in online status or + if ($Monitor) { + Invoke-PCMonitor $getPCComputers + return + } #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) From e60cd96bc6cec0c3b8360d65ad59a04c79888e79 Mon Sep 17 00:00:00 2001 From: Zachary Gorman Date: Tue, 25 Jun 2024 10:17:17 -0700 Subject: [PATCH 2/4] Added PCMonitor.ps1 to fix last commit. Oopsie! --- Private/PCMonitor.ps1 | 46 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 Private/PCMonitor.ps1 diff --git a/Private/PCMonitor.ps1 b/Private/PCMonitor.ps1 new file mode 100644 index 0000000..adf0a5b --- /dev/null +++ b/Private/PCMonitor.ps1 @@ -0,0 +1,46 @@ +function Invoke-Monitor { + param( + [string[]] $comps + ) + # Ask to notify + # Initialize computer sessions + +} + +class WatchDog { + [string]$Hostname + [PSSession]$Session + [string]$LastUser + WatchDog() { $this.Init(@{})} + WatchDog([hashtable]$Properties) { $this.Init($Properties)} + WatchDog([string]$Hostname) { $this.Init(@{Hostname = $Hostname})} + [void] Init([hashtable]$Properties){ + foreach ($prop in $Properties.Keys) { + $this.$prop = $Properties.$prop + } + } + # Returns true if a value was updated + [bool] Update() { + $old = $this + if ((Test-Connection -ComputerName $this.Hostnmae -Count 1)) { + $this.Session = $null + return -not ($old.Session) + } + if (-not ($this.Session)) { + $this.Session = New-PSSession -ComputerName $this.Hostname -SessionOption (New-PSSessionOption -NoMachineProfile) + } + $this.LastUser = $(Invoke-Command -Session $this.Session {Get-ComputerInfo}).CSUserName + if($null -eq $this.LastUser){ + + $this.LastUser = (Invoke-Command -Session $this.Session -ScriptBlock {Get-Process Explorer -IncludeUsername | Where-Object { $_.Username -notlike "*SYSTEM" }} ).Username + + if($null -ne $this.LastUser){ + $this.LastUser = "$($this.LastUser) (RDP/Inactive)" + } + else{ + $this.LastUser = $null + } + } + return (($this.Session -ne $old.Session) -or ($this.LastUser -ne $old.LastUser)) + } +} From 2b0c9ed93c8aee17fc6558c3844940ad294246ff Mon Sep 17 00:00:00 2001 From: Zachary Gorman Date: Mon, 1 Jul 2024 08:34:28 -0700 Subject: [PATCH 3/4] Addded Monitor to monitor a pc's status like online and login status. --- Private/BatchInvokes.ps1 | 2 + Private/PCMonitor.ps1 | 74 +++++++++++++++++++++++++++++++---- Private/UserProfileBackup.ps1 | 3 +- Public/Get-PC.ps1 | 3 +- 4 files changed, 73 insertions(+), 9 deletions(-) diff --git a/Private/BatchInvokes.ps1 b/Private/BatchInvokes.ps1 index 174eb7b..adcdfa5 100644 --- a/Private/BatchInvokes.ps1 +++ b/Private/BatchInvokes.ps1 @@ -52,9 +52,11 @@ function Get-PCBatchInvoke { #Adapter $adapter = ($win32_networkadapterconfiguration | Where-Object {$_.IpEnabled -Match "True"} | Select-Object -Expand Description) + <# if($adapter -is [array]){ $adapter = $adapter[0] } + #> #UserName $Username = $PCInfo.CSUserName diff --git a/Private/PCMonitor.ps1 b/Private/PCMonitor.ps1 index adf0a5b..f7cbcd2 100644 --- a/Private/PCMonitor.ps1 +++ b/Private/PCMonitor.ps1 @@ -1,15 +1,38 @@ -function Invoke-Monitor { +function Invoke-PCMonitor { param( [string[]] $comps ) # Ask to notify + $notify = $(Read-Host "Notify with pop-up window? (y/N)") -match "^[yY]" + if ($notify) { + Add-Type -AssemblyName PresentationFramework + } + $sleepTime = $(Read-Host "Checkin interval in seconds (Default: 300 [5 min])") + if (-not ($sleepTime)) { $sleepTime = 300 } + $dogs = @() # Initialize computer sessions - + foreach ($comp in $comps) { + $dog = [WatchDog]::new($comp) + $null = $dog.Update() + $dogs += $dog + } + while ($true) { + foreach ($dog in $dogs) { + $msg = $dog.ReportChange() + if ($msg) { + if ($notify) { + $null = [System.Windows.MessageBox]::Show($msg) + } + Write-Host "$msg" + } + } + Start-Sleep $sleepTime + } } class WatchDog { [string]$Hostname - [PSSession]$Session + [System.Management.Automation.Runspaces.PSSession]$Session [string]$LastUser WatchDog() { $this.Init(@{})} WatchDog([hashtable]$Properties) { $this.Init($Properties)} @@ -19,12 +42,25 @@ class WatchDog { $this.$prop = $Properties.$prop } } + [string] ToString() { + return ` + "Hostname: $($this.Hostname) `n" + + "Status: $(if ($this.Session) { 'Online' } else { 'Offline' }) `n" + + "User: $($this.LastUser) `n" + } + [WatchDog] Copy() { + $props = @{} + foreach ($prop in $this.PSObject.Properties) { + $props.$($prop.Name) = $prop.Value + } + return [WatchDog]$props + } # Returns true if a value was updated [bool] Update() { - $old = $this - if ((Test-Connection -ComputerName $this.Hostnmae -Count 1)) { + $old = $this.Copy() + if (-not (Test-Connection -ComputerName $this.Hostname -Count 1)) { $this.Session = $null - return -not ($old.Session) + return ($old.Session) } if (-not ($this.Session)) { $this.Session = New-PSSession -ComputerName $this.Hostname -SessionOption (New-PSSessionOption -NoMachineProfile) @@ -43,4 +79,28 @@ class WatchDog { } return (($this.Session -ne $old.Session) -or ($this.LastUser -ne $old.LastUser)) } -} + # Returns a message describing any changes + [string] ReportChange() { + $old = $this.Copy() + if (-not ($this.Update())) { return $null } + $date = Get-Date -Format "[MM/dd/yy HH:MM:ss]" + if ($old.Session -ne $this.Session) { + if ($old.Session -and $this.Session) { + return "$date $($this.Hostname) | Session re-established" + } elseif ($this.Session) { + return "$date $($this.Hostname) | Online" + } else { + return "$date $($this.Hostname) | Offline" + } + } elseif ($old.LastUser -ne $this.LastUser) { + if ($old.LastUser -and $this.LastUser) { + return "$date $($this.Hostname) | $($old.LastUser) logged off and $($this.LastUser) logged on" + } elseif ($old.LastUser) { + return "$date $($this.Hostname) | $($old.LastUser) logged off" + } else { + return "$date $($this.Hostname) | $($this.LastUser) logged on" + } + } + return $null + } +} \ No newline at end of file diff --git a/Private/UserProfileBackup.ps1 b/Private/UserProfileBackup.ps1 index dd1957d..4f8da2f 100644 --- a/Private/UserProfileBackup.ps1 +++ b/Private/UserProfileBackup.ps1 @@ -112,7 +112,6 @@ $SourceRoot = "\\$Computer\c$\Users\$User" $BackupDestination = "\\SHSCMGSRMC\ProfileBackup" $Destination = "\\SHSCMGSRMC\ProfileBackup\$DestinationFileName" - $CopiedUserDesktop = Join-Path -Path $Destination -ChildPath "Desktop" #region BACKUP if($ConfirmUser -eq 'y'){ @@ -155,6 +154,7 @@ Write-Warning "Invalid input please restart script" return } + #Creates a log file New-Item -Path $Destination\backuplog.txt -Force | Write-Verbose $log = Join-Path -Path $Destination -ChildPath backuplog.txt @@ -171,6 +171,7 @@ #Cleans up Citrix Shortcuts Write-Host "Removing Citrix Shortcuts from backup" + $CopiedUserDesktop = Join-Path -Path $Destination -ChildPath "Desktop" $Shortcuts = Get-ChildItem -Path $CopiedUserDesktop -Filter *.lnk foreach($Shortcut in $Shortcuts){ diff --git a/Public/Get-PC.ps1 b/Public/Get-PC.ps1 index 1e83b74..b957c96 100644 --- a/Public/Get-PC.ps1 +++ b/Public/Get-PC.ps1 @@ -4,7 +4,7 @@ #region Module Import Block -$ErrorActionPreference = 'SilentlyContinue' +#$ErrorActionPreference = 'SilentlyContinue' #DevStage can take either Dev or Prod as values $devStage = 'Dev' #Locations for dev build and prod build @@ -544,6 +544,7 @@ Function Get-PC { if ($adTest) { Write-Warning "$comp is either disabled or off the domain" } + Write-Progress -Activity "Looking up computer in AD" -Completed } #Direct SCCM Queries From a77b048b873a6c514a09a039109f0a8f441e87a7 Mon Sep 17 00:00:00 2001 From: Zachary Gorman Date: Mon, 1 Jul 2024 10:32:55 -0700 Subject: [PATCH 4/4] Updated PCMonitor PCMonitor now prompts for a waiting interval, gives user the option to be notified, displays a propress bar when initializing sessions, and updates a datetime so user knows script isn't hanging --- Private/PCMonitor.ps1 | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Private/PCMonitor.ps1 b/Private/PCMonitor.ps1 index f7cbcd2..d16adf2 100644 --- a/Private/PCMonitor.ps1 +++ b/Private/PCMonitor.ps1 @@ -12,20 +12,29 @@ function Invoke-PCMonitor { $dogs = @() # Initialize computer sessions foreach ($comp in $comps) { + Write-Progress -Activity "Initializing sessions" -Status $comp -PercentComplete ($dogs.Length/$comps.Length) $dog = [WatchDog]::new($comp) $null = $dog.Update() $dogs += $dog } + Write-Progress -Activity "Initializing sessions" -Completed while ($true) { + $change = $false foreach ($dog in $dogs) { $msg = $dog.ReportChange() if ($msg) { + $change = $true if ($notify) { $null = [System.Windows.MessageBox]::Show($msg) } Write-Host "$msg" } } + # Update date and time so user knows script hasn't frozen + if (-not ($change)) { + $date = Get-Date -Format "[MM/dd/yy HH:mm:ss]" + Write-Host -NoNewline "$date `r" + } Start-Sleep $sleepTime } }