From f2b358d8dd323aef67f7feb522ecf6c9a65edf30 Mon Sep 17 00:00:00 2001 From: dyoder Date: Fri, 14 Aug 2020 14:19:37 -0400 Subject: [PATCH] update --- Cleanup-AppXTempFiles.ps1 | 9 -- Cleanup-LogFiles.ps1 | 3 - Cleanup-SystemPath.ps1 | 24 ----- Cleanup-TempFiles.ps1 | 15 ---- Deploy-PSModule.ps1 | 9 +- Fix-NinjaRMMData.ps1 | 8 -- Fix-ReregisterWindowsScriptingComponents.ps1 | 29 ------ Fix-SystemPrintQueue.ps1 | 22 ----- Fix-WindowsUpdate.ps1 | 21 ----- Install-DeltekVision.ps1 | 11 ++- PSModule/PSModule-Cleanup.psm1 | 63 +++++++++++++ PSModule/PSModule-Fix.psm1 | 90 +++++++++++++++++++ PSModule/PSModule-Remediation.ps1 | 37 ++++++++ PSModule/PSModule-Remove.psm1 | 19 ++++ PSModule/PSModule-Uninstall.psm1 | 0 PSModule/Set-WinEvtLog.psm1 | Bin 13148 -> 0 bytes Remediation-RestartServices.ps1 | 29 +++--- Remove-AteraAgent.ps1 | 9 -- Remove-DeltekVision.ps1 | 11 --- Remove-LabTech.ps1 | 2 +- Stop-Process.ps1 | 6 +- Uninstall-AteraAgent.ps1 | 11 +++ Remove-Java.ps1 => Uninstall-Java.ps1 | 2 +- Uninstall-LabTech.ps1 | 3 + 24 files changed, 253 insertions(+), 180 deletions(-) delete mode 100644 Cleanup-AppXTempFiles.ps1 delete mode 100644 Cleanup-LogFiles.ps1 delete mode 100644 Cleanup-SystemPath.ps1 delete mode 100644 Cleanup-TempFiles.ps1 delete mode 100644 Fix-NinjaRMMData.ps1 delete mode 100644 Fix-ReregisterWindowsScriptingComponents.ps1 delete mode 100644 Fix-SystemPrintQueue.ps1 delete mode 100644 Fix-WindowsUpdate.ps1 create mode 100644 PSModule/PSModule-Remediation.ps1 delete mode 100644 PSModule/PSModule-Uninstall.psm1 delete mode 100644 PSModule/Set-WinEvtLog.psm1 delete mode 100644 Remove-AteraAgent.ps1 delete mode 100644 Remove-DeltekVision.ps1 create mode 100644 Uninstall-AteraAgent.ps1 rename Remove-Java.ps1 => Uninstall-Java.ps1 (99%) create mode 100644 Uninstall-LabTech.ps1 diff --git a/Cleanup-AppXTempFiles.ps1 b/Cleanup-AppXTempFiles.ps1 deleted file mode 100644 index 3606475..0000000 --- a/Cleanup-AppXTempFiles.ps1 +++ /dev/null @@ -1,9 +0,0 @@ -## This script will remove runaway AppX temp files that can consume 100's of GB on an endpoint - -## Only run this script on Windows 8 or higher endpoints -$WindowsVersion = [double]("{0}.{1}" -f ([System.Environment]::OSVersion.Version).Major,([System.Environment]::OSVersion.Version).Minor) - If ( $WindowsVersion -ge 6.2 ) { - Get-ChildItem -Path "${Env:SystemRoot}\Temp" | Where { $_.Name -like "AppXDeploymentServer_*.evtx" }| Remove-Item -Force - Get-ChildItem -Path "${Env:SystemRoot}\Temp" | Where { $_.Name -like "AppxErrorReport_*.txt" } | Remove-Item -Force - Get-ChildItem -Path "${Env:SystemRoot}\Temp" | Where { $_.Name -like "AppXPackaging_*.evtx" }| Remove-Item -Force - } diff --git a/Cleanup-LogFiles.ps1 b/Cleanup-LogFiles.ps1 deleted file mode 100644 index ca58319..0000000 --- a/Cleanup-LogFiles.ps1 +++ /dev/null @@ -1,3 +0,0 @@ -## This script will delete runaway CBS logs that can take up 100's of GB on an endpoint - -Get-ChildItem -Path "${Env:WINDIR}\Logs\CBS" -File | Where { ( $_.Name -like "CbsPersist_*.log" ) -or ( $_.Name -like "CbsPersist_*.cab" ) } | Remove-Item -Force \ No newline at end of file diff --git a/Cleanup-SystemPath.ps1 b/Cleanup-SystemPath.ps1 deleted file mode 100644 index d09924c..0000000 --- a/Cleanup-SystemPath.ps1 +++ /dev/null @@ -1,24 +0,0 @@ -## Get contents of SYSTEM PATH environment variable -$REG_ENVVAR = 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment' -$CURRENT_PATH = (Get-Itemproperty -Path $REG_ENVVAR -Name Path).Path -$NEW_PATH = $null -$REMOVE_PATH =$null - -## Verify each path -Foreach ( $path in $CURRENT_PATH.Split(";") ) -{ - If ( (Test-Path $path) -or ($path -like "*%*%*") ) - { - If ( $NEW_PATH ) { $NEW_PATH += ";${path}" } - Else { $NEW_PATH = $path } - } - Else - { - If ( $REMOVE_PATH ) { $REMOVE_PATH += ";${path}" } - Else { $REMOVE_PATH = $path } - } -} - -Write-Output "Removed Paths:`n`r${REMOVE_PATH}" - -Set-ItemProperty -Path $REG_ENVVAR -Name Path -Value $NEW_PATH \ No newline at end of file diff --git a/Cleanup-TempFiles.ps1 b/Cleanup-TempFiles.ps1 deleted file mode 100644 index 2321777..0000000 --- a/Cleanup-TempFiles.ps1 +++ /dev/null @@ -1,15 +0,0 @@ -[CmdletBinding()] -param( - [int]$OlderThan=7 -) - -## Create a new timespan to compare with last write date of the target directory -$timedelta = New-TimeSpan -Days $OlderThan - -## Remove all files and directories -Foreach ( $item in (Get-ChildItem -Path "${Env:WinDir}\TEMP") ) { - - ## If it's older than the number of days specified, recursively delete the directory - If ( $item.LastWriteTime -lt ((Get-Date) - $timedelta) ) { Remove-Item $item.FullName -Recurse -ErrorAction SilentlyContinue -Force } - -} \ No newline at end of file diff --git a/Deploy-PSModule.ps1 b/Deploy-PSModule.ps1 index bfbb245..42bc04c 100644 --- a/Deploy-PSModule.ps1 +++ b/Deploy-PSModule.ps1 @@ -13,12 +13,17 @@ If ( Test-Path ${Env:ProgramData} ) ## Set the path to this module and make the directory for it $ModulePath = "${RootDir}\Scripts\${ModuleName}" + +## Create the path to the module If ( !(Test-Path $ModulePath) ) { Try { New-Item -Path $ModulePath -ItemType Directory -Force | Out-Null } Catch { Write-Output $_.Exception.Message } } +## Set the environment variable to the module +[System.Environment]::SetEnvironmentVariable('MSPPSModule',"${RootDir}\Scripts\${ModuleName}",[System.EnvironmentVariableTarget]::Machine) + ## Make sure all the management directories exist If ( !(Test-Path $RootDir) ) { @@ -47,7 +52,3 @@ If ( !(Test-Path "${RootDir}\Logs") ) ## Download the module file Try { (New-Object Net.WebClient).DownloadFile($ModuleURL, "${RootDir}\Scripts\${ModuleName}\${ModuleName}.psm1") } Catch { Write-Output $_.Exception.Message } - -## Import the new module to test -If ( Test-Path "${RootDir}\Scripts\${ModuleName}\${ModuleName}.psm1" ) -{ Import-Module -Name "${RootDir}\Scripts\${ModuleName}\${ModuleName}.psm1" } \ No newline at end of file diff --git a/Fix-NinjaRMMData.ps1 b/Fix-NinjaRMMData.ps1 deleted file mode 100644 index aaf32ac..0000000 --- a/Fix-NinjaRMMData.ps1 +++ /dev/null @@ -1,8 +0,0 @@ -## Stop the NinjaRMMAgent service -Stop-Service 'NinjaRMMAgent' -Force - -## Delete all Ninja's cached data -Remove-Item -Path "${Env:SystemDrive}\ProgramData\NinjaRMMAgent\jsonoutput" -Recurse -Force - -## Start the NinjaRMMAgent service -Start-Service 'NinjaRMMAgent' diff --git a/Fix-ReregisterWindowsScriptingComponents.ps1 b/Fix-ReregisterWindowsScriptingComponents.ps1 deleted file mode 100644 index fc5d656..0000000 --- a/Fix-ReregisterWindowsScriptingComponents.ps1 +++ /dev/null @@ -1,29 +0,0 @@ -## List of all scripting component DLL files -$DLL_FILES = @("${Env:WINDIR}\system32\vbscript.dll", - "${Env:WINDIR}\system32\jscript.dll", - "${Env:WINDIR}\system32\dispex.dll", - "${Env:WINDIR}\system32\scrobj.dll", - "${Env:WINDIR}\system32\scrrun.dll", - "${Env:WINDIR}\system32\wshext.dll" - "${Env:WINDIR}\system32\wshom.ocx", - "${Env:WINDIR}\syswow64\vbscript.dll", - "${Env:WINDIR}\syswow64\jscript.dll", - "${Env:WINDIR}\syswow64\dispex.dll", - "${Env:WINDIR}\syswow64\scrobj.dll", - "${Env:WINDIR}\syswow64\scrrun.dll", - "${Env:WINDIR}\syswow64\wshext.dll", - "${Env:WINDIR}\syswow64\wshom.ocx") - -## Unregister all DLLs -foreach ($dll in $DLL_FILES) { - if ( Test-Path $dll ) { - if ( $dll -Match "syswow64" ) { $REGSVR32 = "${Env:WINDIR}\syswow64\regsvr32" } else { $REGSVR32 = "regsvr32" } - Start-Process "${REGSVR32}" -ArgumentList "/u /s ${dll}" -Wait -}} - -## Register all DLLs -foreach ($dll in $DLL_FILES) { - if ( Test-Path $dll ) { - if ( $dll -Match "syswow64" ) { $REGSVR32 = "${Env:WINDIR}\syswow64\regsvr32" } else { $REGSVR32 = "regsvr32" } - Start-Process "${REGSVR32}" -ArgumentList "/s ${dll}" -Wait -}} \ No newline at end of file diff --git a/Fix-SystemPrintQueue.ps1 b/Fix-SystemPrintQueue.ps1 deleted file mode 100644 index 6a1a4a7..0000000 --- a/Fix-SystemPrintQueue.ps1 +++ /dev/null @@ -1,22 +0,0 @@ -## Make sure the spooler service isn't already stopped -If ( (Get-Service -Name spooler).Status -ne "Stopped" ) -{ - ## Forcefully stop the spooler service - Stop-Service -Name spooler -Force - - ## Wait a few seconds to make sure it's stopped - Start-Sleep -Seconds 5 -} - -## Check to make sure the spooler service has stopped -If ((Get-Service -Name spooler).Status -eq "Stopped") -{ - ## Delete all print jobs, including secure prints - Remove-Item "${Env:WINDIR}\System32\spool\PRINTERS\*" -Recurse - - ## Start the spooler service again - Start-Service -Name spooler -} - -## If the spooler service didn't stop on time, just return an error to the Ninja Activity Stream -Else { Write-Output "Could not clean ${Env:WINDIR}\System32\spool\PRINTERS\* because spooler service is running." } diff --git a/Fix-WindowsUpdate.ps1 b/Fix-WindowsUpdate.ps1 deleted file mode 100644 index db098e7..0000000 --- a/Fix-WindowsUpdate.ps1 +++ /dev/null @@ -1,21 +0,0 @@ -# Delete any existing folder from a previous execution of this script -if ( Test-Path "${Env:WinDir}\SoftwareDistribution.old" ) { Remove-Item "${Env:WinDir}\SoftwareDistribution.old" -Recurse } - -# Stop Background Intelligent Transfer Services and Windows Update -Stop-Service BITS -Stop-Service wuauserv - -# Rename the SoftwareDistribution folder, forcing Windows Update to recreate all metrics and redownload all updates -Rename-Item -Path "${Env:WinDir}\SoftwareDistribution" -NewName "${Env:WinDir}\SoftwareDistribution.old" -Force - -# Start Windows Update and Background Intelligent Transfer Services -Start-Service wuauserv -Start-Service BITS - -# Delete SoftwareDistribution.old from this execution of this script -if ( Test-Path "${Env:WinDir}\SoftwareDistribution.old" ) { Remove-Item "${Env:WinDir}\SoftwareDistribution.old" -Recurse } - -# If you're using WSUS this will force a policy update on the device and then -# reset the device's WSUS authorization and start detecting updates -# If you don't use WSUS and Group Policy, you can leave the following line commented out -#Start-Process "${Env:WinDir}\System32\wuauctl.exe" -ArgumentList "/resetauthorization /detectnow" diff --git a/Install-DeltekVision.ps1 b/Install-DeltekVision.ps1 index 61b92db..e9af7b6 100644 --- a/Install-DeltekVision.ps1 +++ b/Install-DeltekVision.ps1 @@ -1,11 +1,14 @@ param( - [string]$VisionURL + [string]$VisionURL='https://dbia.deltekfirst.com/DBIAClient/DeltekVision.application' ) +## Installation location for shortcut +$InstallLocation = "${Env:Public}\Desktop\Deltek Vision.lnk" + ## Remove the existing shortcut -If ( Test-Path "${Env:UserProfile}\Desktop\Deltek Vision.lnk" ) +If ( Test-Path $InstallLocation ) { - Try { Remove-Item -Path "${Env:UserProfile}\Desktop\Deltek Vision.lnk" -Force } + Try { Remove-Item -Path $InstallLocation -Force } Catch { Write-Output $_.Exception.Message } } @@ -21,7 +24,7 @@ If ( $VisionURL ) Try { $WshShell = New-Object -ComObject WScript.Shell - $Shortcut = $WshShell.CreateShortcut("${Env:UserProfile}\Desktop\Deltek Vision.lnk") + $Shortcut = $WshShell.CreateShortcut($InstallLocation) $Shortcut.Arguments = $VisionURL $Shortcut.Description = "Launch Deltek Vision" $Shortcut.IconLocation = "${IEPATH}, 0" diff --git a/PSModule/PSModule-Cleanup.psm1 b/PSModule/PSModule-Cleanup.psm1 index e69de29..2eda36b 100644 --- a/PSModule/PSModule-Cleanup.psm1 +++ b/PSModule/PSModule-Cleanup.psm1 @@ -0,0 +1,63 @@ +Function global:Cleanup-SystemPath +{ +## Get contents of SYSTEM PATH environment variable +$REG_ENVVAR = 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment' +$CURRENT_PATH = (Get-Itemproperty -Path $REG_ENVVAR -Name Path).Path +$NEW_PATH = $null +$REMOVE_PATH =$null + +## Verify each path +Foreach ( $path in $CURRENT_PATH.Split(";") ) +{ + If ( (Test-Path $path) -or ($path -like "*%*%*") ) + { + If ( $NEW_PATH ) { $NEW_PATH += ";${path}" } + Else { $NEW_PATH = $path } + } + Else + { + If ( $REMOVE_PATH ) { $REMOVE_PATH += ";${path}" } + Else { $REMOVE_PATH = $path } + } +} + +Write-Output "Removed Paths:`n`r${REMOVE_PATH}" + +Set-ItemProperty -Path $REG_ENVVAR -Name Path -Value $NEW_PATH +} + +## This script will remove runaway AppX temp files that can consume 100's of GB on an endpoint +Function global:Cleanup-AppXTempFiles +{ +## Only run this script on Windows 8 or higher endpoints +$WindowsVersion = [double]("{0}.{1}" -f ([System.Environment]::OSVersion.Version).Major,([System.Environment]::OSVersion.Version).Minor) +If ( $WindowsVersion -ge 6.2 ) +{ + Get-ChildItem -Path "${Env:SystemRoot}\Temp" | Where { $_.Name -like "AppXDeploymentServer_*.evtx" }| Remove-Item -Force + Get-ChildItem -Path "${Env:SystemRoot}\Temp" | Where { $_.Name -like "AppxErrorReport_*.txt" } | Remove-Item -Force + Get-ChildItem -Path "${Env:SystemRoot}\Temp" | Where { $_.Name -like "AppXPackaging_*.evtx" }| Remove-Item -Force +} +} + +## This script will delete runaway CBS logs that can take up 100's of GB on an endpoint +Function global:Cleanup-LogFiles +{ +Get-ChildItem -Path "${Env:WINDIR}\Logs\CBS" -File | Where { ( $_.Name -like "CbsPersist_*.log" ) -or ( $_.Name -like "CbsPersist_*.cab" ) } | Remove-Item -Force +} + +Function global:Cleanup-TempFiles +{ +#[CmdletBinding()] +param([int]$OlderThan=7) + +## Create a new timespan to compare with last write date of the target directory +$timedelta = New-TimeSpan -Days $OlderThan + +## Remove all files and directories +Foreach ( $item in (Get-ChildItem -Path "${Env:WinDir}\TEMP") ) +{ + ## If it's older than the number of days specified, recursively delete the directory + If ( $item.LastWriteTime -lt ((Get-Date) - $timedelta) ) { Remove-Item $item.FullName -Recurse -ErrorAction SilentlyContinue -Force } + +} +} \ No newline at end of file diff --git a/PSModule/PSModule-Fix.psm1 b/PSModule/PSModule-Fix.psm1 index e69de29..203f6ea 100644 --- a/PSModule/PSModule-Fix.psm1 +++ b/PSModule/PSModule-Fix.psm1 @@ -0,0 +1,90 @@ +Function global:Fix-WindowsScriptingComponents +{ +## List of all scripting component DLL files +$DLL_FILES = @("${Env:WINDIR}\system32\vbscript.dll", + "${Env:WINDIR}\system32\jscript.dll", + "${Env:WINDIR}\system32\dispex.dll", + "${Env:WINDIR}\system32\scrobj.dll", + "${Env:WINDIR}\system32\scrrun.dll", + "${Env:WINDIR}\system32\wshext.dll" + "${Env:WINDIR}\system32\wshom.ocx", + "${Env:WINDIR}\syswow64\vbscript.dll", + "${Env:WINDIR}\syswow64\jscript.dll", + "${Env:WINDIR}\syswow64\dispex.dll", + "${Env:WINDIR}\syswow64\scrobj.dll", + "${Env:WINDIR}\syswow64\scrrun.dll", + "${Env:WINDIR}\syswow64\wshext.dll", + "${Env:WINDIR}\syswow64\wshom.ocx") + +## Unregister all DLLs +ForEach ($dll in $DLL_FILES) +{ + If ( Test-Path $dll ) + { + If ( $dll -Match "syswow64" ) { $REGSVR32 = "${Env:WINDIR}\syswow64\regsvr32" } Else { $REGSVR32 = "regsvr32" } + Start-Process "${REGSVR32}" -ArgumentList "/u /s ${dll}" -Wait + } +} + +## Register all DLLs +ForEach ($dll in $DLL_FILES) +{ + If ( Test-Path $dll ) + { + If ( $dll -Match "syswow64" ) + { $REGSVR32 = "${Env:WINDIR}\syswow64\regsvr32" } Else { $REGSVR32 = "regsvr32" } + Start-Process "${REGSVR32}" -ArgumentList "/s ${dll}" -Wait + } +} +} + +Function global:Fix-SystemPrintQueue +{ +## Make sure the spooler service isn't already stopped +If ( (Get-Service -Name spooler).Status -ne "Stopped" ) +{ + ## Forcefully stop the spooler service + Stop-Service -Name spooler -Force + + ## Wait a few seconds to make sure it's stopped + Start-Sleep -Seconds 5 +} + +## Check to make sure the spooler service has stopped +If ((Get-Service -Name spooler).Status -eq "Stopped") +{ + ## Delete all print jobs, including secure prints + Remove-Item "${Env:WINDIR}\System32\spool\PRINTERS\*" -Recurse + + ## Start the spooler service again + Start-Service -Name spooler +} + +## If the spooler service didn't stop on time, just return an error +Else { Write-Output "Could not clean ${Env:WINDIR}\System32\spool\PRINTERS\* because spooler service is running." } +} + +Function global:Fix-WindowsUpdate +{ +param([switch]$WSUS) + +## Delete any existing folder from a previous execution of this script +If ( Test-Path "${Env:WinDir}\SoftwareDistribution.old" ) { Remove-Item "${Env:WinDir}\SoftwareDistribution.old" -Recurse -Force } + +## Stop Background Intelligent Transfer Services and Windows Update +Stop-Service BITS +Stop-Service wuauserv + +## Rename the SoftwareDistribution folder, forcing Windows Update to recreate all metrics and redownload all updates +Rename-Item -Path "${Env:WinDir}\SoftwareDistribution" -NewName "${Env:WinDir}\SoftwareDistribution.old" -Force + +## Start Windows Update and Background Intelligent Transfer Services +Start-Service wuauserv +Start-Service BITS + +## Delete SoftwareDistribution.old from this execution of this script +If ( Test-Path "${Env:WinDir}\SoftwareDistribution.old" ) { Remove-Item "${Env:WinDir}\SoftwareDistribution.old" -Recurse -Force } + +## If using WSUS, reset authorization with server and detect new updates +If ( $WSUS ) { Start-Process "${Env:WinDir}\System32\wuauctl.exe" -ArgumentList "/resetauthorization /detectnow" } +} \ No newline at end of file diff --git a/PSModule/PSModule-Remediation.ps1 b/PSModule/PSModule-Remediation.ps1 new file mode 100644 index 0000000..f20ca2b --- /dev/null +++ b/PSModule/PSModule-Remediation.ps1 @@ -0,0 +1,37 @@ +Function global:Remediation-StopProcess +{ +param([string]$Name,[switch]$Force=$false) + +If ( $Name ) +{ + ## Get all matching processes + $Processes = Get-Process | Where { $_.Name -ilike $Name } + + ## Get the total number of matching processes + $NumMatches = $Processes.Count + + If ( $NumMatches -ge 1 ) + { + ## Forcefully close matching processes + If ( $Force ) + { + Foreach ( $proc in $Processes ) { Stop-Process $proc -Force -ErrorAction SilentlyContinue } + Write-Output "Forcefully closed ${NumMatches} matching instance(s) of ${Name}" + } + + ## Gracefully close matching processes + Else + { + Foreach ( $proc in $Processes ) { $proc.CloseMainWindow() | Out-Null } + Write-Output "Gracefully closed ${NumMatches} matching instance(s) of ${Name}" + + } + } + + Else { Write-Output "No running processes match the name ${Name}" } +} + +Else { Write-Output "No process name was specified!" } +} + +Export-ModuleMember -Function Remediation-StopProcess \ No newline at end of file diff --git a/PSModule/PSModule-Remove.psm1 b/PSModule/PSModule-Remove.psm1 index e69de29..c492778 100644 --- a/PSModule/PSModule-Remove.psm1 +++ b/PSModule/PSModule-Remove.psm1 @@ -0,0 +1,19 @@ +Function global:Remove-DeltekVision +{ +## Stop the DeltekVision process +Remediation-StopProcess -Name "DeltekVision" -Force + +## Set the path to Deltek Vision +$APP_PATH = "${Env:UserProfile}\AppData\Local\Apps\2.0" + +## Test to make sure it's installed for the current user before continuing +If ( Test-Path $APP_PATH ) +{ + ## Delete the existing installed app + Try { Remove-Item $APP_PATH -Recurse -Force } + Catch { Write-Output $_.Exception.Message } + +} Else { Write-Output "${APP_PATH} does not exist!" } +} + +Export-ModuleMember -Function Remove-DeltekVision diff --git a/PSModule/PSModule-Uninstall.psm1 b/PSModule/PSModule-Uninstall.psm1 deleted file mode 100644 index e69de29..0000000 diff --git a/PSModule/Set-WinEvtLog.psm1 b/PSModule/Set-WinEvtLog.psm1 deleted file mode 100644 index 5c99707af4628554dbca5616fe893601f29faafa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13148 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