public/Test-ServiceRebootPending.ps1
function Test-ServiceRebootPending { <# .SYNOPSIS Checks for services that need to be restarted. .DESCRIPTION Checks for services that need to be restarted. .EXAMPLE Test-ServiceRebootPending Checks for services that need to be restarted. .NOTES Display services which need to be restarted, because they are still using old copies of libraries. Written by Richard W.M. Jones <rjones@redhat.com> License: GNU General Public License version 2 or above Requires: - lsof - systemctl source: https://github.com/atc0005/needs-restart/blob/master/needs-restart.pl .LINK https://github.com/Skatterbrainz/linuxtools/blob/master/docs/Test-ServiceRebootPending.md #> [CmdletBinding()] param() # Parse lsof output. $lsofOutput = & lsof -F cpLfn $lines = $lsofOutput -split "`n" $procs = @() $pidx = $null $comm = $null $user = $null $fd = $null $file = $null foreach ($line in $lines) { $line = $line.Trim() if ($line -match "^p(\d+)") { $pidx = $matches[1] continue } elseif ($line -match "^c(.*)") { $comm = $matches[1] continue } elseif ($line -match "^L(.*)") { $user = $matches[1] continue } elseif ($line -match "^f(.*)") { $fd = $matches[1] continue } elseif ($line -match "^n(.*)") { $file = $matches[1] $file = $file -replace ";[a-f0-9]{8}", "" if ($fd -eq "DEL" -and $file -match "\.so") { $procs += [PSCustomObject]@{ comm = $comm pid = $pidx user = $user file = $file } } } } $services_cache = @{} $pkgs_cache = @{} $pkgs_service_restart = @{} $pkgs_scope_restart = @{} $pkgs_pid_restart = @{} foreach ($proc in $procs) { if (-not $services_cache.ContainsKey($proc.pid)) { $service = & systemctl status $proc.pid | Select-Object -First 1 $services_cache[$proc.pid] = $service } $service = $services_cache[$proc.pid] if (-not $pkgs_cache.ContainsKey($proc.file)) { $pkg = "" if (Test-Path '/usr/bin/dpkg') { $pkg = & dpkg -S $proc.file 2>&1 } elseif (Test-Path '/usr/bin/rpm') { $pkg = & rpm -qf $proc.file 2>&1 } else { throw "Failed to identify distribution specific packaging tool" } if (![string]::IsNullOrEmpty($pkg)) { $pkgs_cache[$proc.file] = $pkg.ToString().Trim() } } $pkg = $pkgs_cache[$proc.file] if ($service -match "\.service - ") { if (![string]::IsNullOrEmpty($pkg)) { if ($pkgs_service_restart.ContainsKey($pkg)) { $pkgs_service_restart[$pkg][$service] = $true } else { $pkgs_service_restart[$pkg] = @{$service = $true} } } } elseif ($service -match "\.scope - ") { if (![string]::IsNullOrEmpty($pkg)) { if ($pkgs_scope_restart.ContainsKey($pkg)) { $pkgs_scope_restart[$pkg][$service] = $true } else { $pkgs_scope_restart[$pkg] = @{$service = $true} } } } else { if (![string]::IsNullOrEmpty($pkg)) { if ($pkgs_pid_restart.ContainsKey($pkg)) { $pkgs_pid_restart[$pkg] += $proc } else { $pkgs_pid_restart[$pkg] = @($proc) } } } } # Print out the services to restart summary. foreach ($pkg in $pkgs_service_restart.Keys) { $services = $pkgs_service_restart[$pkg].Keys foreach ($service in $services) { [pscustomobject]@{ Package = $pkg Type = "service" Identity = $($service -replace "● ", "") Action = "restart" } } } # Print out the scopes to restart summary. foreach ($pkg in $pkgs_scope_restart.Keys) { $services = $pkgs_scope_restart[$pkg].Keys foreach ($service in $services) { [pscustomobject]@{ Package = $pkg Type = "user" Identity = $($service -replace "● ", "") Action = "log out and log in" } } } # Print out the PIDs to restart summary. foreach ($pkg in $pkgs_pid_restart.Keys) { $processes = $pkgs_pid_restart[$pkg] foreach ($proc in $processes) { [pscustomobject]@{ Package = $pkg Type = "process" Identity = @{comm = $proc.comm; PID = $proc.pid; Owner = $proc.user} Action = "restart" } } } } |