diff --git a/Connect-MSO365.ps1 b/Connect-MSO365.ps1 deleted file mode 100644 index f3d3a4e..0000000 --- a/Connect-MSO365.ps1 +++ /dev/null @@ -1,32 +0,0 @@ -#Requires -Version 3.0 - -param([string]$User) - -## Install ExchangeOnlineManagement module if it doesn't already exist -If ( !(Get-Module -ListAvailable -Name ExchangeOnlineManagement) ) -{ - Try { Install-Module -Name ExchangeOnlineManagement } - Catch { Write-Output $_.Exception.Message ; Exit } -} -Import-Module ExchangeOnlineManagement - -Connect-ExchangeOnline -UserPrincipalName $User -ShowProgress $true - - -#$Groups = Get-UnifiedGroup -ResultSize Unlimited -#$Groups | ForEach-Object { -# $group = Get-UnifiedGroupLinks -Identity $_.Name -LinkType Members -ResultSize Unlimited -# $group | ForEach-Object { -# New-Object -TypeName PSObject -Property @{ -# Group = $group.DisplayName -# Member = $_.Name -# EmailAddress = $_.PrimarySMTPAddress -# RecipientType= $_.RecipientType -# } -# } -#} | Export-CSV “${Env:UserProfile}\Desktop\group-export.csv" -NoTypeInformation -Encoding UTF8 - - - - -Disconnect-ExchangeOnline \ No newline at end of file diff --git a/Control-Process.ps1 b/Control-Process.ps1 deleted file mode 100644 index 54e75eb..0000000 --- a/Control-Process.ps1 +++ /dev/null @@ -1,32 +0,0 @@ -## Stop a process -Function End-Process -{ - param( - [Parameter(Mandatory=$true,ValueFromPipeline=$true)][string[]]$Name, - [Parameter(Mandatory=$false)][switch]$Match=$false, - [Parameter(Mandatory=$false)][switch]$Force - ) - ForEach ( $item in $Name ) { - $process = Get-Process -Name $item -ErrorAction SilentlyContinue - If ( !($process) ) { - LogMsg "Cannot find the process '${item}'" - If ( $Match ) { - LogMsg "Attempting to match '${item}' to all running process names" - ForEach ( $proc in ((Get-Process | Where { $_.Name -match $item }).Name) ) { - If ( $Force ) { End-Process -Name $proc -Force } Else { End-Process -Name $proc } - } - } - } - Else { - $name = $process.Name - If ( $Force ) { - LogMsg "Forcefully stopping '${name}' process" - Stop-Process $process -Force -ErrorAction SilentlyContinue - } - Else { - LogMsg "Attempting to gracefully close '${name}' process" - $process.CloseMainWindow() | Out-Null - } - } - } -} diff --git a/Create-ISOShare.ps1 b/Create-ISOShare.ps1 deleted file mode 100644 index dd9cdeb..0000000 --- a/Create-ISOShare.ps1 +++ /dev/null @@ -1,117 +0,0 @@ -#Requires -Version 3.0 - -<# -.SYNOPSIS - This script will mount an ISO file and share it on the network. -.DESCRIPTION - The ISO file can be a local path or fetched from a URL. The share this script creates will allow 'Everyone' read-only access. -.PARAMETER ShareName - This is the name of the Windows share that will be created. -.PARAMETER ISOPath - The full absolute path to the ISO. This can be a local path or a URL. -.PARAMETER NoShare - Will prevent the script from creating a network share. It will return only the drive letter for the mounted ISO file. -.PARAMETER Persist - Will cause the ISO to remain mounted even after rebooting the endpoint. -.PARAMETER Redownload - If -ISOPath is a URL, this parameter will delete an existing ISO file with the same name and download a fresh copy. -.PARAMETER Remove - Will remove the network share, and dismount the ISO file. This will not delete the ISO file. -.INPUTS - None. This script does not accept pipeline input. -.OUTPUTS - This script will output only a string containing the status of the shared ISO file. -.EXAMPLE - .\Create-ISOShare.ps1 -ShareName 'Win10Setup' -ISOPath 'D:\path\to\windows_10_setup.iso' -.EXAMPLE - .\Create-ISOShare.ps1 -ShareName 'Win10Setup' -ISOPath 'D:\path\to\windows_10_setup.iso' -Remove -.EXAMPLE - .\Create-ISOShare.ps1 -ShareName 'Win10Setup' -ISOPath 'https://hosted.net/path/to/windows_10_setup.iso' -.EXAMPLE - .\Create-ISOShare.ps1 -ISOPath 'https://hosted.net/path/to/windows_10_setup.iso' -NoShare -.NOTES - This script requires an administrative token to run properly. -.LINK - https://www.microsoft.com/en-us/software-download/windows10 -#> - -param( - [string]$ShareName, - [string]$ISOPath, - [switch]$NoShare, - [switch]$Persist=$false, - [switch]$Redownload, - [switch]$Remove -) - -## Set the download directory for downloaded ISO file -## Note: This is only needed if a URL is passed to -ISOPath -$DownloadDirectory = $Env:SYSTEMDRIVE - -## Download the ISO if a URL is specified -If ( $ISOPath.StartsWith('http') ) -{ - ## Get the URL into its own variable - $DownloadURL = $ISOPath - - ## Get the file name from the URL - $filename = Split-Path -Path $DownloadURL -Leaf - - ## Set the path to the soon-to-be-downloaded ISO file - $ISOPath = "${DownloadDirectory}\${filename}" - - ## If $Redownload is specified, delete the ISO so we can redownload it - If ( ($Redownload) -and (Test-Path $ISOPath) ) { Remove-Item $ISOPath -Force } -} - -## Function to remove the share and dismount the ISO -Function Remove-ISOShare -{ - ## Remove the share - Remove-SMBShare -Name $ShareName -Force -ErrorAction SilentlyContinue - - ## Dismount the ISO file - If ( Test-Path $ISOPath ) { Dismount-DiskImage -ImagePath $ISOPath -StorageType ISO | Out-Null } -} - -## Just remove the share and dismount the ISO if $Remove is specified -If ( $Remove ) { Remove-ISOShare } - -## If $Remove is not specified, mount the ISO and create a network share -Else -{ - ## If $DownloadURL exists and the ISO doesn't, download it - If ( ($DownloadURL) -and (!(Test-Path $ISOPath)) ) - { - (New-Object System.Net.WebClient).DownloadFile($DownloadURL, $ISOPath) - } - - ## Make sure we remove the share and mounted ISO, since both might already exist - Remove-ISOShare - - ## Mount the ISO and get the drive letter - $MountResult = Mount-DiskImage -ImagePath $ISOPath -StorageType ISO -Access ReadOnly -PassThru - $DriveLetter = ($MountResult | Get-Volume).DriveLetter - - ## Create network share - If (! ($NoShare) ) - { - New-SMBShare -Name $ShareName -Path "${DriveLetter}:\" -ContinuouslyAvailable:$Persist -ReadAccess 'Everyone' | Out-Null - } - - ## Get the share path (or local path if it isn't shared) - If ( $NoShare ) { $SharePath = "${DriveLetter}:\" } - Else { $SharePath = "\\${Env:COMPUTERNAME}\${ShareName}" } - If ( Test-Path $SharePath ) - { - ## Return the full share path - Write-Output "ISO Share Path:`n`r${SharePath}" - - ## Return the full command to upgrade Windows 10 using this share - Write-Output "Windows 10 upgrade command:`n`r${SharePath}\setup.exe /auto upgrade /dynamicupdate disable /showoobe none /quiet" - - } Else { Write-Output "ISO could not be shared." } - - - -} \ No newline at end of file diff --git a/Create-LocalAdmin.bat b/Create-LocalAdmin.bat deleted file mode 100644 index 19976c4..0000000 --- a/Create-LocalAdmin.bat +++ /dev/null @@ -1,63 +0,0 @@ -@echo off - -rem Print a quick help message if nothing is passed to this script -if "%~1"=="" ( -set SCRIPT=%~0 -echo Create local administrator user account -echo. -echo Usage: -echo %SCRIPT% -u [username] -p [password] -n [display name] -echo. -echo Example: -echo %SCRIPT% -u myadmin -p p@ssw0rd -n "My Admin" -goto end -) - -rem Get the params passed in on the command line -:parse -if "%~1"=="" goto endparse -if "%~1"=="-u" set USER=%2 -if "%~1"=="-p" set PASS=%2 -if "%~1"=="-n" set NAME=%2 -shift -shift -goto parse -:endparse - -rem Make sure we don't run this on a domain controller -wmic os get producttype | find "2" 1>nul 2>nul && goto domain-controller - -rem Make sure the specified user doesn't already exist -net user | find /i "%USER%" >nul || goto create-admin -goto reset-password - -rem Create a new user with the specified name and password -:create-admin -net user %USER% %PASS% /add /fullname:"%NAME%" /active:yes /expires:never /passwordreq:yes /times:all -goto make-admin - -rem If the specified user already exists, reset it's password -:reset-password -net user %USER% %PASS% /fullname:"%NAME%" /active:yes /expires:never /passwordreq:yes /times:all - -rem Add the specified user to the local Administrators group if it isn't already a member -rem Note: if you're using Restricted Groups in an Active Directory GPO, this change may be overwritten at the next policy application -net localgroup Administrators | find /i "%USER%" >nul || goto make-admin -goto remove-logon -:make-admin -net localgroup Administrators %USER% /add - -rem Remove user from logon screen -:remove-logon -if exist "%ProgramFiles(x86)%" ( - reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\SpecialAccounts\UserList" /v "%USER%" /t REG_DWORD /d 0 /f /reg:64 >nul - goto finish-remove-logon -) -reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\SpecialAccounts\UserList" /v "%USER%" /t REG_DWORD /d 0 /f >nul -:finish-remove-logon -goto end - -:domain-controller -rem This computer is a domain controller. The local %USER% account cannot be created. - -:end \ No newline at end of file diff --git a/Deploy-PSModule.ps1 b/Deploy-PSModule.ps1 deleted file mode 100644 index 79dffd0..0000000 --- a/Deploy-PSModule.ps1 +++ /dev/null @@ -1,57 +0,0 @@ -## Set the MSP name and environment variable -$MSPName = "Emberkom" - -## Set the name of the module to deploy -$ModuleName = "PSModule" - -## Define base URL for downloading module file -$ModuleURL = "https://dev.emberkom.com/emberkom/management-scripts/raw/branch/master/${ModuleName}/${ModuleName}.psm1" - -## Setup the MSP management directories -If ( Test-Path ${Env:ProgramData} ) -{ $MSPRoot = "${Env:ProgramData}\${MSPName}" } Else { $MSPRoot = "${Env:SystemDrive}\${MSPName}" } -$MSPScripts = "${MSPRoot}\Scripts" -$MSPTools = "${MSPRoot}\Tools" -$MSPLogs = "${MSPRoot}\Logs" - -## Set the path to this module and make the directory for it -$ModulePath = "${MSPRoot}\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',"${MSPRoot}\Scripts\${ModuleName}",[System.EnvironmentVariableTarget]::Machine) - -## Make sure all the management directories exist -If ( !(Test-Path $MSPRoot) ) -{ - Try { New-Item -Path $MSPRoot -ItemType Directory -Force | Out-Null } - Catch { Write-Output $_.Exception.Message } -} -If ( !(Test-Path $MSPScripts) ) -{ - Try { New-Item -Path $MSPScripts -ItemType Directory -Force | Out-Null } - Catch { Write-Output $_.Exception.Message } -} -If ( !(Test-Path $MSPTools) ) -{ - Try { New-Item -Path $MSPTools -ItemType Directory -Force | Out-Null } - Catch { Write-Output $_.Exception.Message } -} -If ( !(Test-Path $MSPLogs) ) -{ - Try { New-Item -Path $MSPLogs -ItemType Directory -Force | Out-Null } - Catch { Write-Output $_.Exception.Message } -} - -## Create environment variable for the root MSP directory -[System.Environment]::SetEnvironmentVariable('MSPDir',"${MSPRoot}",[System.EnvironmentVariableTarget]::Machine) - -## Download the module file -Try { (New-Object Net.WebClient).DownloadFile($ModuleURL, "${MSPRoot}\Scripts\${ModuleName}\${ModuleName}.psm1") } -Catch { Write-Output $_.Exception.Message } diff --git a/Disable-TabletMode.ps1 b/Disable-TabletMode.ps1 index a8b34a3..667c0a8 100644 --- a/Disable-TabletMode.ps1 +++ b/Disable-TabletMode.ps1 @@ -1,5 +1,5 @@ $RegKey = 'HKCU:SOFTWARE\Microsoft\Windows\CurrentVersion\ImmersiveShell' -. 'C:\Users\dyoder\Emberkom\Data\Projects\development\management-scripts\Tools.ps1' + ## Make sure endpoint is running at least Windows 8 If ( IsWindowsVersion -ge '6.3' ) { diff --git a/Fix-WindowsHealth(old).ps1 b/Fix-WindowsHealth(old).ps1 deleted file mode 100644 index a2177fd..0000000 --- a/Fix-WindowsHealth(old).ps1 +++ /dev/null @@ -1,137 +0,0 @@ -[CmdletBinding()] -param( - [switch]$SkipDiskRepair=$true, - [switch]$PostRestart=$false -) - -## Set the file name for this script when copying to $ScriptDirectory -## Note: the .ps1 file extension will be automatically added -$ScriptName = "Fix-WindowsHealth" - -## File to log messages into -$LogFile = "${MSPLogs}\${ScriptName}.log" - -## Copy script locally and schedule chkdsk at next boot -If ( ($PostRestart -eq $false) -and ($SkipDiskRepair -eq $false) ) { - - ## Copy this script so it can be run post-reboot - If (! (Test-Path $ScriptDirectory) ) { New-Item -Path $ScriptDirectory -ItemType Directory -Force | Out-Null } - $ScriptFile = "${ScriptDirectory}\${ScriptName}.ps1" - If ( $ScriptFile -ne $MyInvocation.MyCommand.Definition ) { - If ( Test-Path $ScriptFile ) { - Remove-Item $ScriptFile -Force - } - Copy-Item -Path $MyInvocation.MyCommand.Definition -Destination $ScriptFile -Force - If ( Test-Path $ScriptFile ) { - Log $LogFile "Successfully copied running script to: ${ScriptFile}" - } Else { Log $LogFile "Failed to copy running script to: ${ScriptFile}" } - } - - ## Schedule chkdsk for next reboot - & cmd.exe /c echo y `| chkdsk.exe /f /r /x - Log $LogFile "Scheduled chkdsk.exe for next reboot" - - ## Create a RunOnce task to resume this script after the disk has been repaired - $command = """%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe"" -ExecutionPolicy Bypass -File ""${ScriptFile}"" -PostRestart" - Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce" -Name $ScriptName -Value $command - If ( (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce" -Name $ScriptName) ) { - Log $LogFile "Successfully scheduled post-reboot task: ${command}" - } Else { Log $LogFile "Failed to schedule post-reboot task" } -} - -## Get the last log entry from chkdsk -If ( $PostRestart ) { - - ## Get the last event chkdsk recorded in the Event Log - $chkdskmsg = Get-EventLog -LogName 'Application' -Source 'Wininit' -Newest 1 -ErrorAction SilentlyContinue - If ( $chkdskmsg ) { - - ## Export the chkdsk log to a separate file for review - $ChkdskLog = "${LogDirectory}\${ScriptName}-Chkdsk.log" - If ( Test-Path $ChkdskLog ) { - Remove-Item $ChkdskLog -Force - } - New-Item -Path $ChkdskLog -ItemType File -Value $chkdskmsg.Message.ToString() - If ( Test-Path $ChkdskLog ) { - Log $LogFile "Successfully exported chkdsk result" - } Else { Log $LogFile "Failed to export chkdsk result" } - - } Else { Log $LogFile "Last chkdsk result could not be obtained" } -} - -## Cleanup online image and restore health -If ( $PostRestart -or $SkipDiskRepair ) { - - ## Run enhanced DISM for Windows 8 and higher assets - If ( IsWindowsVersion -ge "6.2" ) { - - $BeginDISMRun = $(Get-Date).AddSeconds(-1) - - ## Scan the Windows Component Store for problems - Log $LogFile "Beginning Windows Component Store scan" - Start-Process "dism.exe" -ArgumentList "/online /cleanup-image /scanhealth" -Wait - Log $LogFile "Completed Windows Component Store scan" - - ## Check to see if the previous command recorded any problems that need repairing - Log $LogFile "Beginning Windows Component Store health check" - $CheckHealthOutput = $(dism /online /cleanup-image /checkhealth) | Out-String - If ( $CheckHealthOutput -match "repairable" ) { - - Log $LogFile "Completed Windows Component Store health check: Problems found" - - ## Repair problems with the Windows Component Store - Log $LogFile "Beginning Windows Component Store restoration" - Start-Process "dism.exe" -ArgumentList "/online /cleanup-image /restorehealth" -Wait - Log $LogFile "Completed Windows Component Store restoration" - } Else { Log $LogFile "Completed Windows Component Store health check: No problems found" } - - $EndDISMRun = $(Get-Date).AddSeconds(1) - - ## Parse DISM log file for recent activity - $DISMLogFile = "${LogDirectory}\${ScriptName}-DISM.log" - If ( Test-Path $DISMLogFile ) { Remove-Item $DISMLogFile -Force } - New-Item -Path $DISMLogFile -ItemType File - Log $LogFile "Beginning Windows Component Store log data collection" - Get-Content -Path "${Env:WinDir}\Logs\DISM\dism.log" | Select-String -Pattern '^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})' | - % { If ( ((Get-Date $_.Line.Substring(0,19)) -gt $BeginDISMRun) -and ((Get-Date $_.Line.Substring(0,19)) -le $EndDISMRun) ) { - Add-Content -Path $DISMLogFile -Value $_.Line - } - } - - Log $LogFile "Completed Windows Component Store log data collection" - - } Else { Log $LogFile "Online image cleanup and restoration is only supported on Windows 8 and higher" } -} - -## Run SFC -If ( $PostRestart -or $SkipDiskRepair ) { - - ## Start the TrustedInstaller service if it isn't running - ## Note: this is necessary for the SFC utility to function properly - If ( (Get-Service -Name TrustedInstaller).Status -ne "Running" ) { - Restart-Service -Name TrustedInstaller -Force - Log $LogFile "Started TrustedInstaller service" - } - - ## Start the SFC utility to check validity of Windows system files - Log $LogFile "Beginning SFC scan and fix" - - $BeginSFCRun = $(Get-Date).AddSeconds(-1) - Start-Process "sfc" -ArgumentList "/scannow" -Wait - $EndSFCRun = $(Get-Date).AddSeconds(1) - Log $LogFile "Completed SFC scan and fix" - - ## Parse the CBS.log file and export any SFC related messages - $SFCLogFile = "${LogDirectory}\${ScriptName}-SFC.log" - If ( Test-Path $SFCLogFile ) { Remove-Item $SFCLogFile -Force } - New-Item -Path $SFCLogFile -ItemType File - Log $LogFile "Beginning SFC log data collection" - Get-Content -Path "${Env:WinDir}\Logs\CBS\CBS.log" | Select-String -Pattern '^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2}).+\[SR\]' | - % { If ( ((Get-Date $_.Line.Substring(0,19)) -gt $BeginSFCRun) -and ((Get-Date $_.Line.Substring(0,19)) -le $EndSFCRun) ) { - Add-Content -Path $SFCLogFile -Value $_.Line - } - } - Log $LogFile "Completed SFC log data collection" -} - -## Prepare Log File Upload diff --git a/Fix-WindowsHealth.bat b/Fix-WindowsHealth.bat deleted file mode 100644 index a116baa..0000000 --- a/Fix-WindowsHealth.bat +++ /dev/null @@ -1,34 +0,0 @@ -@echo off - -rem ## Scan the Windows Component Store for problems -dism /online /cleanup-image /scanhealth >nul - -rem ## Check to see if the previous command recorded any problems that need repairing -rem ## If there aren't any problems, jump to the section labeled skip-restorehealth -dism /online /cleanup-image /checkhealth | find /i "repairable" >nul || goto :skip-restorehealth - -rem ## If there are problems with the Windows Component Store, repair them -rem ## Once the repair operation completes, jump to the section labeled run-sfc -dism /online /cleanup-image /restorehealth >nul - -rem ## If the Windows Component Store gets repaired, the Ninja activity feed will -rem ## see the following line: -echo The component store has been repaired. -goto run-sfc - -rem ## This scetion only runs if there aren't any problems to repair -:skip-restorehealth - -rem ## If the Windows Component Store is healthy, the Ninja activity feed will -rem ## see the following line: -echo No component store corruption detected. - -rem ## This section runs the sfc utility -:run-sfc - -rem ## Check to see if the TrustedInstaller is running, if not then start it -rem ## This avoids a common problem with sfc not starting -sc query trustedinstaller | find /i "running" >nul || net start trustedinstaller >nul - -rem ## This will take a while and the output of sfc will be recorded in a text file -sfc /scannow > %SystemDrive%\sfcoutput.txt \ No newline at end of file diff --git a/Fix-WindowsUpdate.ps1 b/Fix-WindowsUpdate.ps1 index 2a3a3c2..561723f 100644 --- a/Fix-WindowsUpdate.ps1 +++ b/Fix-WindowsUpdate.ps1 @@ -1,48 +1,35 @@ -param([switch]$WSUS) +## This is the folder we need to rename +$TARGET_DIR = "${Env:WinDir}\SoftwareDistribution" -LogMsg "Fix-WindowsUpdate.ps1" +## This is what we're renaming it to +$DEST_DIR = "${Env:WinDir}\SoftwareDistribution.old" ## Delete any existing folder from a previous execution of this script -If ( Test-Path "${Env:WinDir}\SoftwareDistribution.old" ) -{ - LogMsg "Deleting ""${Env:WinDir}\SoftwareDistribution.old""" - Try { Remove-Item "${Env:WinDir}\SoftwareDistribution.old" -Recurse -Force } - Catch { LogErr $_.Exception.Message } -} +LogMsg "Deleting ""${DEST_DIR}""" +Try { Remove-Item $DEST_DIR -Recurse -Force -ErrorAction SilentlyContinue } +Catch { LogErr $_.Exception.Message } ## Stop Background Intelligent Transfer Services and Windows Update -LogMsg "Stopping BITS service" -Try { Stop-Service BITS } -Catch { LogErr $_.Exception.Message } -LogMsg "Stopping wuauserv service" -Try { Stop-Service wuauserv } -Catch { LogErr $_.Exception.Message } +Control-Service -Stop -Name BITS +Control-Service -Stop -Name wuauserv ## Rename the SoftwareDistribution folder, forcing Windows Update to recreate all metrics and redownload all updates -LogMsg "Renaming ""${Env:WinDir}\SoftwareDistribution"" to ""${Env:WinDir}\SoftwareDistribution.old""" -Try { Rename-Item -Path "${Env:WinDir}\SoftwareDistribution" -NewName "${Env:WinDir}\SoftwareDistribution.old" -Force } +LogMsg "Renaming ""${TARGET_DIR}"" to ""${DEST_DIR}""" +Try { Rename-Item -Path $TARGET_DIR -NewName $DEST_DIR -Force } Catch { LogErr $_.Exception.Message } ## Start Windows Update and Background Intelligent Transfer Services -LogMsg "Starting wuauserv service" -Try { Start-Service wuauserv } -Catch { LogErr $_.Exception.Message } -LogMsg "Starting BITS service" -Try { Start-Service BITS } -Catch { LogErr $_.Exception.Message } +Control-Service -Start -Name BITS +Control-Service -Start -Name wuauserv ## Delete SoftwareDistribution.old from this execution of this script -If ( Test-Path "${Env:WinDir}\SoftwareDistribution.old" ) -{ - LogMsg "Deleting ""${Env:WinDir}\SoftwareDistribution.old""" - Try { Remove-Item "${Env:WinDir}\SoftwareDistribution.old" -Recurse -Force } - Catch { LogErr $_.Exception.Message } -} +## Comment this section out if you want to leave the renamed folder there for some reason, +## but keep in mind this folder can be very large and takes up a lot of space. +LogMsg "Deleting ""${DEST_DIR}""" +Try { Remove-Item $DEST_DIR -Recurse -Force -ErrorAction SilentlyContinue } +Catch { LogErr $_.Exception.Message } -## If using WSUS, reset authorization with server and detect new updates -If ( $WSUS ) -{ - LogMsg "Resetting WSUS authorization and starting update detection" - Try { Start-Process "${Env:WinDir}\System32\wuauctl.exe" -ArgumentList "/resetauthorization /detectnow" } - Catch { LogErr $_.Exception.Message } -} \ No newline at end of file +## Force the Windows Update client to check for new updates +LogMsg "Resetting WSUS authorization and starting update detection" +Try { Start-Process "${Env:WinDir}\System32\wuauctl.exe" -ArgumentList "/resetauthorization /detectnow" } +Catch { LogErr $_.Exception.Message } \ No newline at end of file diff --git a/Get-NETFrameworkVersion.bat b/Get-NETFrameworkVersion.bat deleted file mode 100644 index 3efc638..0000000 --- a/Get-NETFrameworkVersion.bat +++ /dev/null @@ -1,8 +0,0 @@ -@echo off - -rem This script will return the highest installed version of the .NET Framework (versions 1.0 to 4.6.2) - -rem Test for .NET 4.6.2 -rem reg query HLM\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Client 1>NUL 2>NUL || SET /A "INSTALL=INSTALL-1" - -reg query HKLM\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Client /v Release \ No newline at end of file diff --git a/Install-EmberkomBackup.ps1 b/Install-EmberkomBackup.ps1 deleted file mode 100644 index 4f489c9..0000000 --- a/Install-EmberkomBackup.ps1 +++ /dev/null @@ -1,32 +0,0 @@ -### -# This script exists in N-Central's Automation Manager -### - -param( - [string]$ShortName = "EK", - [string]$LongName = "Emberkom", - [string]$NotificationEmail = "notification@emberkom.com" -) - -Function source { . 'C:\Users\dyoder\Emberkom\Data\Projects\development\management-scripts\Tools.ps1' } -source - -## Because the N-Central Automation Manager can't actually read the full Powershell syntax, we have to first put the passed in variables -## into new variables so we can reference the RMM generated data in the standard form and not with the curly braces -$short = $ShortName -$long = $LongName -$email = $NotificationEmail - -$account = "${short}_${Env:COMPUTERNAME}".ToUpper() -$email = $email.ToLower() - -## URL to download the branded WholesaleBackup installer -$URL = "http://downloads.backupops.com/4Windows/${MSPName}Backup_installer.exe" - -## Silent installation options -$Arguments = "/SP- /VERYSILENT /NORESTART /WPUSH /WACCOUNT ""${account}"" /WORG ""${long}"" /WEMAIL ""${email}""" - -## Install Emberkom Backup -#Install-Program -Path $(Download-File -URL $URL) -Arguments $Arguments -Delete - -Write-Output $Arguments \ No newline at end of file diff --git a/Install-LiquidFilesOutlookAgent.ps1 b/Install-LiquidFilesOutlookAgent.ps1 index c272e24..c364b8f 100644 --- a/Install-LiquidFilesOutlookAgent.ps1 +++ b/Install-LiquidFilesOutlookAgent.ps1 @@ -18,9 +18,7 @@ Catch { LogErr $_.Exception.Message } ## Delete installer Try { - If ( Test-Path $INSTALLER ) { - LogMsg "Deleting downloaded installation package" - Remove-Item $INSTALLER -Force - } + LogMsg "Deleting downloaded installation package" + Remove-Item $INSTALLER -Force -ErrorAction SilentlyContinue } Catch { LogErr $_.Exception.Message } \ No newline at end of file diff --git a/Install-Nextcloud.ps1 b/Install-Nextcloud.ps1 index f13f910..65b1152 100644 --- a/Install-Nextcloud.ps1 +++ b/Install-Nextcloud.ps1 @@ -1,9 +1,6 @@ ## Define URL for downloading the installer $URL = 'https://dev.emberkom.com/emberkom/management-scripts/raw/branch/master/resources/Nextcloud-3.0.3-setup.exe' -#$FILE = '{0}{1}' -f (GetTempPath), (Split-Path $URL -Leaf) -#$FILE = Download-File -URL $URL -File $FILE - ## Stop app if it's currently running End-Process -Name 'nextcloud' -Force diff --git a/PSModule/old/PSModule-SetWinEvtLog.psm1 b/PSModule/old/PSModule-SetWinEvtLog.psm1 deleted file mode 100644 index 96121b4..0000000 --- a/PSModule/old/PSModule-SetWinEvtLog.psm1 +++ /dev/null @@ -1,152 +0,0 @@ -Function global:Set-WinEvtLog { - <# - .SYNOPSIS - Enable/Disable an event log. - .DESCRIPTION - Enable or disable a Windows Event Log using the System.Diagnostics.Eventing.Reader.EventLogConfiguration object. - This function only outputs terminating errors to the console. If you want to see more detail use -verbose - .EXAMPLE - Set-WinEvtLog -Enable -Log "Microsoft-Windows-DNS-Client/Operational" - .EXAMPLE - Set-WinEvtLog -Disable -Log (Get-Content ListOfLogs.txt) - .EXAMPLE - Get-Content ListOfLogs.txt | Set-WinEvtLog -Enable - .PARAMETER Log - The log(s) to modIfy. - .PARAMETER Enable - Enables the log(s). - .PARAMETER Disable - Disables the log(s). - #> - - [CmdletBinding(SupportsShouldProcess=$True,ConfirmImpact='Low')] - param - ( - [Parameter(Mandatory=$True, - ValueFromPipeline=$False, - ValueFromPipelineByPropertyName=$True, - HelpMessage='Which log do you want to enable?')] - [string[]]$Log, - [Parameter(Mandatory=$True, - ValueFromPipelineByPropertyName=$True, - ParameterSetName = 'Enable')] - [Switch]$Enable, - [Parameter(Mandatory=$True, - ValueFromPipelineByPropertyName=$True, - ParameterSetName = 'Disable')] - [Switch]$Disable - ) - - Begin - { - # Keep track of changes made to event logs in a separate file. - $RecordLog = "${Env:MSPDir}\Logs\WinEvtLogs-Enabled.log" - - If ( !(Test-Path -Path $RecordLog) ) - { - # Create the record keeping log file If it doesn't exist. - $NewFile = ((New-Item -Path $RecordLog -ItemType file).name | Out-String) - $NewFile = $NewFile.Trim() - Write-Verbose "$NewFile did not exist and has been created." - } - } - - Process - { - # Make sure Record Keeping is properly configured, otherwise exit. - If ( !($RecordLog) ) - { - Write-Verbose "The record keeping log does not exist, this function will not continue." - Return - } - - # Loop through the name(s) in the $Log variable passed to this function. - ForEach ($name in $Log) - { - # Process the data only If the script should Process data. - If ( $pscmdlet.ShouldProcess($name, 'Enable Log') ) - { - # Load the RecordLog into a variable. - $PreviouslyEnabledLogs = Get-Content $RecordLog - - # Determine whether to Enable or Disable logging of the specIfied log. - Switch ($PSCmdlet.ParameterSetName) - { - 'Enable' { $SetEnable = $True } - 'Disable' { $SetEnable = $False } - } - - # Create a new object for the specIfied log. - $LogObject = New-Object System.Diagnostics.Eventing.Reader.EventLogConfiguration $name - - # Set the variable to determine whether the log has been enabled by this script or not - $IsEnabledByFunction = $False - - # Determine whether or not the log had been enabled by this function. - ForEach ($item in $PreviouslyEnabledLogs) - { If ($item -eq $name) { $IsEnabledByFunction = $True } } - - # Act based on whether the log is already enabled or not. - Switch ($logObject.IsEnabled) - { - $True - { - # Inform user whether this log has been enabled by this function or not. - If ($IsEnabledByFunction) - { Write-Verbose "$name has previously been enabled by this function." } - Else { Write-Verbose "$name has previously been enabled, but not by this function." } - } - - $False - { - # Inform user that this log has been disabled by something other than this function. - If ($IsEnabledByFunction) - { Write-Verbose "$name should already be enabled by this function, but has been disabled by other means." } - } - } - - # ModIfy the log to either enable or disable it. - If ($LogObject.IsEnabled -eq $SetEnable) - { Write-Verbose "$name is already in the desired state." } - Else - { - # Set the log to the desired state. - $LogObject.IsEnabled = $SetEnable - - # Save changes to the log. - $LogObject.SaveChanges() - - # VerIfy the change has been made. - Switch ($LogObject.IsEnabled) - { - $True - { - Write-Verbose "$name has been enabled." - - # Make sure this log wasn't already enabled by this function so we don't write the same name more than once in $RecordLog - If (!($IsEnabledByFunction)) { Add-Content -Path $RecordLog "$name" } - } - - $False - { - # Remove $name from $RecordLog If it was put there by this function. - If ($IsEnabledByFunction) - { - # Clear the contents of $RecordLog - Clear-Content -Path $RecordLog - - # Add each item back in that was already there except for the current $name - ForEach ($filename In $PreviouslyEnabledLogs) - { If ($filename -ne $name) { Add-Content -Path $RecordLog $filename} } - } - Write-Verbose "$name has been disabled." - } - } - } - } - } - } - - end {} -} -Export-ModuleMember -Function Set-WinEvtLog \ No newline at end of file diff --git a/PSModule/old/PSModule.psm1 b/PSModule/old/PSModule.psm1 deleted file mode 100644 index ad2656b..0000000 --- a/PSModule/old/PSModule.psm1 +++ /dev/null @@ -1,158 +0,0 @@ -#Requires -Version 2.0 - -## Set the name of this module -$ModuleName = "PSModule" - -## Define base URL for updating modules and resources -$BaseURL = "https://dev.emberkom.com/emberkom/management-scripts/raw/branch/master/${ModuleName}" - -## Set the path to this module -$ModulePath = "${Env:MSPDir}\Scripts\${ModuleName}" - -## Define the paths for where we'll place stuff on the endpoint -$MSPRoot = $Env:MSPDir -$MSPScripts = "${MSPRoot}\Scripts" -$MSPTools = "${MSPRoot}\Tools" -$MSPLogs = "${MSPRoot}\Logs" - -## Function to simply import a module and return an error message if it fails -Function Load-Module -{ - param([string]$modulename) - - ## Get a new copy of the module - Get-Module $modulename - - ## Form the local file path to the specified module - $FilePath = "${ModulePath}\${modulename}.psm1" - - ## Import the module - If ( Test-Path $FilePath ) - { - Try { Import-Module -Name $FilePath } - Catch { Write-Output $_.Exception.Message } - } Else { Write-Output "Module does not exist: ${FilePath}" } -} - -## Function to update or install a module -Function Get-Module -{ - param([string]$modulename) - - ## Form the URL to the specified module - $ModuleURL = "${BaseURL}/${modulename}.psm1" - - ## Form the local file path to the specified module - $FilePath = "${ModulePath}\${modulename}.psm1" - - ## Download the new file, overwriting the local copy - If ( IsDownloadable $ModuleURL ) - { - Try { (New-Object Net.WebClient).DownloadFile($ModuleURL, $FilePath) } - Catch { Write-Output $_.Exception.Message } - } Else { Write-Output "Could not download ${ModuleURL}" } -} - -## Determines whether a file can be downloaded or not -Function IsDownloadable -{ - param([string]$url) - - ## Create a web request - $HTTPRequest = [System.Net.WebRequest]::Create($url) - - Try - { - ## Get the response - $HTTPResponse = $HTTPRequest.GetResponse() - - ## Save the status code - $HTTPStatus = [int]$HTTPResponse.StatusCode - } - Catch [System.Net.WebException] { $HTTPResponse = $_.Exception.Response } - - ## Close the connection, because we're done with it - Finally { $HTTPResponse.Close() } - - ## Test to make sure we received a status of 200 "OK" from the resource - If ($HTTPStatus -eq 200) { Return $true } - - ## If the status code is anything other than 200, return $false - Else { Return $false } -} - -## EXPORT FUNCTION -## Function to log activity to the configured log directory -Function global:Log -{ - Begin {} - Process {} - End {} -} - -## EXPORT FUNCTION -## Function to determine if the current user context is an Administrator -Function global:IsAdmin -{ - Begin {} - Process - { - If ( ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) ) - { Return $true } Else { Return $false } - } - End {} -} - -## EXPORT FUNCTION -## Function to retrieve and run a powershell script -Function Run-PSScript -{ - param( - [string]$Type='management-scripts', - [string]$Name, - [string]$Arguments - ) - - ## Form the URL to the specified script - $URL = "https://dev.emberkom.com/emberkom/${Type}/raw/branch/master/${Name}.ps1" - - If ( IsDownloadable $URL ) - { - $Script = (New-Object Net.WebClient).DownloadString($URL) - $ScriptBlock = [Scriptblock]::Create($Script) - Try { Invoke-Command -ScriptBlock $ScriptBlock -ArgumentList $Arguments } - Catch { Write-Output $_.Exception.Message } - } Else { Write-Output "Could not retrieve ${URL}" } -} - -## Make sure all the management directories exist -If ( !(Test-Path $MSPRoot) ) -{ - Try { New-Item -Path $MSPRoot -ItemType Directory -Force | Out-Null } - Catch { Write-Output $_.Exception.Message } -} -If ( !(Test-Path $MSPScripts) ) -{ - Try { New-Item -Path $MSPScripts -ItemType Directory -Force | Out-Null } - Catch { Write-Output $_.Exception.Message } -} -If ( !(Test-Path $MSPTools) ) -{ - Try { New-Item -Path $MSPTools -ItemType Directory -Force | Out-Null } - Catch { Write-Output $_.Exception.Message } -} -If ( !(Test-Path $MSPLogs) ) -{ - Try { New-Item -Path $MSPLogs -ItemType Directory -Force | Out-Null } - Catch { Write-Output $_.Exception.Message } -} - -## Import all modules -$ListOfModules = @( - "PSModule", - "PSModule-SetWinEvtLog" -) -ForEach ($module in $ListOfModules) { Load-Module $module } - -## Make sure this module exports only the functions that should be exported -Export-ModuleMember -Function Log,IsAdmin,Run-PSScript \ No newline at end of file diff --git a/PSModule/older/PSModule-Cleanup.psm1 b/PSModule/older/PSModule-Cleanup.psm1 deleted file mode 100644 index e69de29..0000000 diff --git a/PSModule/older/PSModule-Create.psm1 b/PSModule/older/PSModule-Create.psm1 deleted file mode 100644 index e69de29..0000000 diff --git a/PSModule/older/PSModule-Fix.psm1 b/PSModule/older/PSModule-Fix.psm1 deleted file mode 100644 index e69de29..0000000 diff --git a/PSModule/older/PSModule-Get.psm1 b/PSModule/older/PSModule-Get.psm1 deleted file mode 100644 index e69de29..0000000 diff --git a/PSModule/older/PSModule-Install.psm1 b/PSModule/older/PSModule-Install.psm1 deleted file mode 100644 index e69de29..0000000 diff --git a/PSModule/older/PSModule-Remediation.psm1 b/PSModule/older/PSModule-Remediation.psm1 deleted file mode 100644 index e69de29..0000000 diff --git a/PSModule/older/PSModule-Remove.psm1 b/PSModule/older/PSModule-Remove.psm1 deleted file mode 100644 index e69de29..0000000 diff --git a/PSModule/older/PSModule-Start.psm1 b/PSModule/older/PSModule-Start.psm1 deleted file mode 100644 index e69de29..0000000 diff --git a/PSModule/older/PSModule-Upload.psm1 b/PSModule/older/PSModule-Upload.psm1 deleted file mode 100644 index e69de29..0000000 diff --git a/Remediation-StopProcess.ps1 b/Remediation-StopProcess.ps1 deleted file mode 100644 index a0a7c75..0000000 --- a/Remediation-StopProcess.ps1 +++ /dev/null @@ -1,32 +0,0 @@ -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!" } \ No newline at end of file diff --git a/Remove-NinjaRMMAppPatchingCache.ps1 b/Remove-NinjaRMMAppPatchingCache.ps1 deleted file mode 100644 index 42d0c4c..0000000 --- a/Remove-NinjaRMMAppPatchingCache.ps1 +++ /dev/null @@ -1,3 +0,0 @@ -## Cleanup Ninja's 3pp cache -If ( Test-Path "${Env:SystemDrive}\ProgramData\NinjaRMMAgent\components\app-patching\SIGNATURES" ) -{ Remove-Item "${Env:SystemDrive}\ProgramData\NinjaRMMAgent\components\app-patching\SIGNATURES" -Force -Recurse } diff --git a/Remove-OldFiles.ps1 b/Remove-OldFiles.ps1 deleted file mode 100644 index 387fbbd..0000000 --- a/Remove-OldFiles.ps1 +++ /dev/null @@ -1,31 +0,0 @@ -<# -.SYNOPSIS -Remove files older than the specified number of days. - -.DESCRIPTION -This script will delete all files in a directory which are older than the specified number of days. -It will not search recursively for files and will only look in the directory specified. - -.PARAMETER --Path -This is the directory to search for old files - -.PARAMETER --OlderThan -This is the number of days that limits the files that are deleted. -Anything newer than the value specified here will be retained, while anything older than the value specified here will be deleted. - -.EXAMPLE -Remove-OldFiles -Path "C:\Windows\TEMP" -OlderThan 30 -This will remove all files in C:\Windows\TEMP that are older than 30 days -#> - -Param( - [string]$Path="C:\Users\dyoder\Desktop", - [int]$OlderThan=7 -) - -If ( Test-Path $Path ) { - $files = Get-ChildItem $Path | Where { !$_.PSIsContainer -and $_.LastWriteTime -lt (Get-Date).AddDays(-${OlderThan}) } - foreach ( $f in $files ) { write-host $f.FullName } -} Else { Write-Host "The path does not exist: ${Path}" } \ No newline at end of file diff --git a/Set-RebootSchedule.ps1 b/Set-RebootSchedule.ps1 deleted file mode 100644 index 92c6949..0000000 --- a/Set-RebootSchedule.ps1 +++ /dev/null @@ -1,678 +0,0 @@ -<# - -.SYNOPSIS -Provides friendly messages reminding a user to restart their computer based on events that require it. - -.DESCRIPTION -The Set-RebootSchedule script is called from any computer management software to notify a user of a required restart. -This script accepts several different parameters which change the messages displayed to the user. -Some logic is used when determining the best time to remind the user to restart. - -.PARAMETER SysPerf -The -SysPerf parameter will remind the user to restart due to system performance. -This parameter should be called if the computer has had consistently high memory usage, recurring application hangs, or stuck processes. -If this parameter is used it will simply tell the user that a restart is needed to improve overall stability. - -.PARAMETER OSUpdate -The -OSUpdate parameter will remind the user to restart due to operating system updates. - -.PARAMETER Uptime -The -Uptime parameter will remind the user to restart due to long uptimes. -This script does not define the length of time the computer has been on, but will display the number of days to the end user. -If the computer has been on for 10 days and this parameter is used, it will tell the user this computer has been on for 10 days. - -.PARAMETER AllowMinimize -The -AllowMinimize parameter will let the prompts and reminders be minimized by the user. -By default, the user is not allowed to minimize the window. - -.PARAMETER Override -The -Override parameter is used with either the -OSUpdate or -Uptime parameters. -This parameter will override the priority of the existing reminder schedule and overwrite any existing schedule with the one set when -Override is called. -See the NOTES section for additional information on schedule priorities. - -.PARAMETER Remove -The -Remove parameter will simply delete any scheduled restart reminder. - -.PARAMETER Task -The -Task parameter will allow this script to run without scheduling a task. This switch is called when this task creates a scheduled task of itself. - -.EXAMPLE -Set-RebootSchedule -SysPerf -Prompt the user to restart because you've seen problems in multiple areas of the computer. - -.EXAMPLE -Set-RebootSchedule -OSUpdate -Prompt the user to restart because Windows was recently updated. - -.EXAMPLE -Set-RebootSchedule -Uptime -Prompt the user to restart because the computer has been up for a long time. - -.EXAMPLE -Set-RebootSchedule -OSUpdate -Override -Prompt the user to restart because Windows was recently updated, overwriting any existing reminder schedule. - -.EXAMPLE -Set-RebootSchedule -Uptime -Override -Prompt the user to restart because the computer has been up for a long time, overwriting any existing reminder schedule. - -.EXAMPLE -Set-RebootSchedule -Remove -There is no longer a need to remind the user to restart, or you just want to clear an existing reminder schedule. - -.NOTES -Calling this script with no parameters does nothing, the script will just exit without prompting the user for anything. - -This is the order of schedule priority when this script is called: - 1.) SysPerf - 2.) OSUpdate - 3.) Uptime - -If -Uptime is called but a schedule has already been set by -OSUpdate, the user will not be prompted to schedule a restart. -If -OSUpdate is called but a schedule has already been set by -SysPerf, the user will not be prompted to schedule a restart. -If -SysPerf is called but a schedule has already been set by -OSUpdate, the user will be prompted to schedule a restart and the existing schedule will be overwritten. - -The -Override parameter is used to modify this logic such that a lower priority schedule can overwrite a higher priority schedule. - -#> - -## Define parameters -Param( - [switch]$SysPerf, - [switch]$OSUpdate, - [switch]$Uptime, - [switch]$AllowMinimize=$false, - [switch]$Override, - [switch]$Force, - [switch]$Remove -) - -## Add Windows Forms support to this script -Add-Type -AssemblyName System.Windows.Forms -[System.Windows.Forms.Application]::EnableVisualStyles() - -## Functions and subroutines -#region begin FUNCTIONS { - -## Copy this script to a directory where it can be called by a scheduled task -Function Copy-ThisScript { - - ## Get the current directory path and file name of this script - $ThisDirectory = Split-Path -Parent $MyInvocation.PSCommandPath - $ThisScript = Split-Path -Leaf $MyInvocation.PSCommandPath - - ## Check to make sure we don't copy this script if it's already been copied to $CopyDirectory - If ( !($ThisDirectory -eq $CopyDirectory) ) { - - ## Create the destination directory if it doesn't already exist - If ( !(Test-Path -Path $CopyDirectory) ) { New-Item -ItemType Directory -Force -Path $CopyDirectory } - - ## Delete the existing script in $CopyDirectory - If ( Test-Path -Path "${CopyDirectory}\${CopyFilename}" ) { Remove-Item -Path "${CopyDirectory}\${CopyFilename}" -Force } - - ## Copy the script to $CopyDirectory\$CopyFilename - Copy-Item -Path "${ThisDirectory}\${ThisScript}" -Destination "${CopyDirectory}\${CopyFilename}" - } -} - -## Gets the number of days the system has been up. -Function Get-UptimeDays { - - ## Get a new instance of the Win32_OperatingSystem WMI object - $WMIOS = Get-WmiObject Win32_OperatingSystem - - ## Get the last boot time and convert it to a DateTime value - $LastBootTime = $WMIOS.ConvertToDateTime($WMIOS.LastBootUpTime) - - ## Get the number of days since the last time the system was powered on - [string]$Uptime = (New-TimeSpan -Start $LastBootTime -End $(Get-Date)).Days.ToString() - - Return $Uptime -} - -## Determines whether the logo can be downloaded or not -Function IsLogoDownloadable { - - ## Create a web request - $HTTPRequest = [System.Net.WebRequest]::Create($LogoURL) - - ## Get the response - Try { $HTTPResponse = $HTTPRequest.GetResponse() } - - ## Catch any error2 when trying to connect to the resource (including 404) - Catch [System.Net.WebException] { $HTTPResponse = $_.Exception.Response } - - ## Save the status code - $HTTPStatus = [int]$HTTPResponse.StatusCode - - ## Close the connection, because we're done with it - $HTTPResponse.Close() - - ## Test to make sure we received a status of 200 "OK" from the resource - If ($HTTPStatus -eq 200) { Return $true } - - ## If the status code is anything other than 200, return $false so we can do something else - Else { Return $false } -} - -## Returns the local path of a file downloaded from a URL -Function Get-LogoPath { - - ## Get the file name from $url - $filename = [System.IO.Path]::GetFileName($LogoURL) - - ## Set the destination to download to - $localpath = "${Env:TEMP}\${filename}" - - ## Make sure the file is downloadable - If ( IsLogoDownloadable ) { - - ## Try downloading the file - Try { (New-Object Net.WebClient).DownloadFile($LogoURL, $localpath) } - - ## If you want to handle any download errors, put that code in here - Catch { $_ } - } - - ## Now that the file *may* be downloaded, check to make sure it exists - If ( Test-Path $localpath ) { - - ## Return $localpath to the caller - Return $localpath - } - - ## If $localpath doesn't exist (ie: from a previous execution of this script) then return $false - Else { Return $false } -} - -## Base64 encode something -Function Get-Base64($data) { - $bytes = [System.Text.Encoding]::Unicode.GetBytes($data) - $encoded = [Convert]::ToBase64String($bytes) - Return $encoded -} - -## Create a scheduled task -Function Create-ScheduledTask([string]$name,[string]$description,$action,$principal,$trigger) { - - ## Unregister any existing task with the same name as the one we're trying to create - ## This needs to be fixed. If the task does not exist, it throws an error. - Try { Unregister-ScheduledTask -TaskName $name -Confirm:$false } - Catch { $_ } - - ## Configure the task - $Task = New-ScheduledTask -Description $description -Action $action -Principal $principal -Trigger $trigger - - ## Register the scheduled task - Register-ScheduledTask -TaskName $name -InputObject $Task -} - -## Create a task to delete another task -## This will run at boot time to make sure that the user doesn't get unnessarily disrupted by -## a previously scheduled restart task after the computer has already been restarted. -Function Create-DeleteTask([string]$tasktodelete) { - - ## Create a RunOnce task to delete the specified task in the Task Scheduler - ## PROBLEM: How can this occur if the user isn't an admin? - ## Will this work the same if we write to HKCU instead? - #Set-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce" -Name '!DeleteScheduledRebootReminder' -Value "schtasks.exe /Delete /TN ${tasktodelete} /F" - - ## Set the task name - $TaskName = "${CompanyAbbr} - Delete Task: ${tasktodelete}" - - ## Se the task description - $TaskDescription = "This task deletes the task: ${tasktodelete}" - - ## Configure the task action - $args = "/delete /tn " + '"' + "\${tasktodelete}" + '"' + " /f" - $TaskAction = New-ScheduledTaskAction -Execute "schtasks.exe" -Argument $args - - ## Configure the user account the task will run under - $TaskPrincipal = New-ScheduledTaskPrincipal -UserId "LOCALSERVICE" -LogonType ServiceAccount - - ## Configure the trigger to start at the specified time - $Trigger = New-ScheduledTaskTrigger -AtStartup - -} - -## Create a restart task -#Function Create-RestartTask([datetime]$starttime) { -# -# ## Set the task name -# $TaskName = "${CompanyAbbr} - Computer Restart Task" -# -# ## Set the task description -# $TaskDescription = "This task restarts the computer" -# -# ## Convert $script to Base64 -# $EncodedScript = Get-Base64 $RestartComputerTaskScript -# -# ## Configure the task action -# $TaskAction = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-WindowStyle Hidden -NonInteractive -ExecutionPolicy Bypass -EncodedCommand ${EncodedScript}" -# -# ## Configure the user account the task will run under -# $TaskPrincipal = New-ScheduledTaskPrincipal -UserId "LOCALSERVICE" -LogonType ServiceAccount -# -# ## Configure the trigger to start at the specific time -# $Trigger = New-ScheduledTaskTrigger -Once -At $starttime -# -# ## Create a new task to delete the one we're about to create the next time the compter boots -# Create-DeleteTask $TaskName -# -# ## Create the restart task -# Create-ScheduledTask $TaskName $TaskDescription $TaskAction $TaskPrincipal $TaskTrigger -#} - -## Create a reminder task -#Function Create-ReminderTask([datetime]$starttime) { -# -# ## Set the task name -# $TaskName = "${CompanyAbbr} - Computer Restart Reminder Task" -# -# ## Set the task description -# $TaskDescription = "This task reminds the user to restart their computer" -# -# ## Convert $script to Base64 -# $EncodedScript = Get-Base64 $ReminderTaskScript -# -# ## Configure the task action -# $TaskAction = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-WindowStyle Hidden -NonInteractive -ExecutionPolicy Bypass -EncodedCommand ${EncodedScript}" -# -# ## Configure the user account the task will run under -# $TaskPrincipal = New-ScheduledTaskPrincipal -UserId "LOCALSERVICE" -LogonType ServiceAccount -# -# ## Configure the trigger to start at boot -# $Trigger = New-ScheduledTaskTrigger -Once -At $starttime -# -# ## Create the restart task -# Create-ScheduledTask $TaskName $TaskDescription $TaskAction $TaskPrincipal $TaskTrigger -# -# ## Create a new task to delete the one we just created the next time the compter boots -# Create-DeleteTask $TaskName -#} - -## Create a reminder task -Function Create-ReminderTask([datetime]$starttime) { - - ## Set the task name - $TaskName = "${CompanyAbbr} - Computer Restart Reminder Task" - - ## Set the task description - $TaskDescription = "This task reminds the user to restart their computer" - - ## Convert $script to Base64 - $EncodedScript = Get-Base64 $ReminderTaskScript - - ## Configure the task action - $TaskAction = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-ExecutionPolicy Bypass -File `"${CopyDirectory}\${CopyFilename}`"" - - ## Configure the user account the task will run under - $TaskPrincipal = New-ScheduledTaskPrincipal -UserId "LOCALSERVICE" -LogonType ServiceAccount - - ## Configure the trigger to start at boot - $Trigger = New-ScheduledTaskTrigger -Once -At $starttime - - ## Create the restart task - Create-ScheduledTask $TaskName $TaskDescription $TaskAction $TaskPrincipal $TaskTrigger - - ## Create a new task to delete the one we just created the next time the compter boots - Create-DeleteTask $TaskName -} - -## Determine if the current time is earlier than the given time -#Function EarlierThan($time) { -# -# ## If it's earlier, return $true -# If ( (Get-Date) -lt $time ) { Return $true } -# -# ## If it's later, return false -# Else { Return $false } -#} - -## Get the closest time to schedule a restart -#Function Get-NearestRestartTime { -# -# ## Find out what day it is -# switch ( (Get-Date).DayOfWeek ) { -# -# ## On weekends, the nearest time to schedule a restart will be: -# ## 1.) Lunch time -# ## 2.) Sometime in the afternoon -# ## 3.) About 20 minutes from the current time -# { $WeekendDays -contains $_ } { -# -# ## If it's earlier than $Lunchime, return $LunchTime -# If ( EarlierThan $LunchTime ) { Return $LunchTime } -# -# ## If it's earlier than $AfternoonTime, return $AfternoonTime -# ElseIf ( EarlierThan $AfternoonTime ) { Return $AfternoonTime } -# -# ## If it's after $AfternoonTime, return $ShortTimeFromNow -# Else { Return $ShortTimeFromNow } -# break -# } -# ## Throughout the week the nearest time to remind to restart will be: -# ## 1.) Lunch time -# ## 2.) Close of business -# ## 3.) Late at night -# { $WeekDays -contains $_ } { -# -# ## If it's earlier than $LunchTime, return $LunchTime -# If ( EarlierThan $LunchTime ) { Return $LunchTime } -# -# ## If it's earlier than $CloseOfBusiness, return $CloseOfBusiness -# ElseIf ( EarlierThan $CloseOfBusiness ) { Return $CloseOfBusiness } -# -# ## If it's after $CloseOfBusiness, return $LateAtNight -# Else { Return $LateAtNight } -# break -# } -# default { break } -# } -#} - -## Get the next time to remind the user to restart -#Function Get-NextReminderTime { -# -# ## Find out what day it is -# switch ( (Get-Date).DayOfWeek ) { -# -# { $TwoDayReminderDays -contains $_ } { -# -# ## Add 2 days to the current day, then add the $ReminderDelay -# $next = $StartOfBusiness + (New-TimeSpan -Days 2) + $ReminderDelay -# Return $next -# break -# } -# -# { $OneDayReminderDays -contains $_ } { -# -# ## Add 1 day to the current day, then add the $ReminderDelay -# $next = $StartOfBusiness + (New-TimeSpan -Days 1) + $ReminderDelay -# Return $next -# break -# } -# default { break } -# } -#} - -Function Get-NextReminderTime { - - $next = (Get-Date) + $ReminderInterval - Return $next - -} - -## Builds the Windows form to display to the user -Function Display-Prompt([string]$message) { - - ## Set the form's overall parameters - $Form = New-Object System.Windows.Forms.Form - $Form.ClientSize = '400,360' - $Form.Text = $WindowTitle - $Form.TopMost = $true - $Form.MaximizeBox = $false - $Form.MinimizeBox = $AllowMinimize - $Form.FormBorderStyle = 'FixedDialog' - $Form.StartPosition = 'CenterScreen' - - ## Download the logo - $Logo = (Get-LogoPath) - - ## Add a picturebox to the form - If ( $Logo ) { - $pbLogo = New-Object system.Windows.Forms.PictureBox - $pbLogo.Width = $Form.ClientSize.Width - 20 - $pbLogo.Height = 90 - $pbLogo.Anchor = [System.Windows.Forms.AnchorStyles]::None - $pbLogo.Location = New-Object System.Drawing.Point(10,10) - $pbLogo.ImageLocation = $Logo - $pbLogo.SizeMode = [System.Windows.Forms.PictureBoxSizeMode]::CenterImage - $Form.Controls.Add($pbLogo) - } - - ## If the logo isn't available, add label to the form instead of a picturebox - Else { - $lblCompany = New-Object System.Windows.Forms.Label - $lblCompany.Text = $CompanyName - $lblCompany.AutoSize = $false - ## The TextAlign enumerations can be found here: - ## https://docs.microsoft.com/en-us/dotnet/api/system.drawing.contentalignment?view=netframework-2.0 - $lblCompany.TextAlign = 32 - $lblCompany.Width = $Form.ClientSize.Width - 20 - $lblCompany.Height = 60 - $lblCompany.Location = New-Object System.Drawing.Point(10,10) - $lblCompany.Font = 'Microsoft Sans Serif,24,style=Bold' - $Form.Controls.Add($lblCompany) - } - - ## This is the label that contains the reason for the restart - $lblReason = New-Object System.Windows.Forms.Label - $lblReason.Text = $message - $lblReason.AutoSize = $false - $lblReason.TextAlign = 1 - $lblReason.Width = $Form.ClientSize.Width - 50 - $lblReason.Height = 180 - $lblReason.Location = New-Object System.Drawing.Point(25,100) - $lblReason.Font = 'Microsoft Sans Serif,11' - $Form.Controls.Add($lblReason) - - ## This is the label that contains a static message about how to proceed - $lblProceed = New-Object System.Windows.Forms.Label - $lblProceed.Text = $ProceedText - $lblProceed.AutoSize = $true - $lblProceed.TextAlign = 1 - $lblProceed.Location = New-Object System.Drawing.Point(25,280) - $lblProceed.Font = 'Microsoft Sans Serif,11' - $Form.Controls.Add($lblProceed) - -# ## This is the button that displays the nearest time to schedule a reboot -# $btnNearestTime = New-Object System.Windows.Forms.Button -# $btnNearestTime.Text = (Get-Date -Date $NearestRestartTime -Format "hh:mm tt").ToString() -# $btnNearestTime.Width = 130 -# $btnNearestTime.Height = 30 -# $btnNearestTime.Location = New-Object System.Drawing.Point(45,310) -# $btnNearestTime.Font = 'Microsoft Sans Serif,11' -# $btnNearestTime.Add_Click({ -# -# ## Create the "Computer Restart Task" scheduled task -# Create-ReminderTask $NearestRestartTime -# -# ## We're done for now, just close the window. -# $Form.Close() -# }) - - ## This is the button that displays the nearest time to schedule a reboot - $btnNearestTime = New-Object System.Windows.Forms.Button - $btnNearestTime.Text = $RebootNowText - $btnNearestTime.Width = 130 - $btnNearestTime.Height = 30 - $btnNearestTime.Location = New-Object System.Drawing.Point(45,310) - $btnNearestTime.Font = 'Microsoft Sans Serif,11' - $btnNearestTime.Add_Click({ - - ## Create the "Computer Restart Task" scheduled task - Restart-Computer - - ## We're done for now, just close the window. - $Form.Close() - }) - - $Form.AcceptButton = $btmNearestTime - $Form.Controls.Add($btnNearestTime) - - ## This is the placebo button, it just closes the form when clicked. - ## The reminder schedule has already been created, so this button doesn't need to do anything. - $btnPlacebo = New-Object System.Windows.Forms.Button - $btnPlacebo.Text = $PlaceboText - $btnPlacebo.Width = 130 - $btnPlacebo.Height = 30 - $btnPlacebo.Location = New-Object System.Drawing.Point(225,310) - $btnPlacebo.Font = 'Microsoft Sans Serif,11' - $btnPlacebo.Add_Click({ $Form.Close() }) - $Form.Controls.Add($btnPlacebo) - - - [void]$Form.ShowDialog() -} - -#endregion FUNCTIONS } - -#region begin SCRIPTS { - -## This script is used to remind the user to restart their computer -$ReminderTaskScript = '&{ -## code here -}' - -#endregion SCRIPTS } - -## Define custom company name, logo, window title, and messages -#region begin CUSTOMIZATIONS { - -## The following 2 settings are specific to your company -## This is the name of your company. -$CompanyName = "Emberkom" -## This is the short or abbreviated name of your company -## It's used to prefix the scheduled tasks so they're easy to identify -$CompanyAbbr = "EK" -## This is the URL to your company logo. -## If your company logo cannot be downloaded, $CompanyName will be used instead. -## If the image you specify is larger than 380x90, it will shrink to fit that size. -$LogoURL = 'https://emberkom.s3.amazonaws.com/management/scripts/resources/small-web-logo.jpg' - -## This script will start by copying itself into a local directory on the computer. -## This will allow the scheduled tasks this script creates to call it later. -## Directory to copy this script into (do not put in an ending "\") -$CopyDirectory = "${Env:ProgramData}\${CompanyName}\Scripts" -## The name of the file this script should have when copied to the $CopyDirectory -$CopyFilename = "Set-RebootSchedule.ps1" - -## The following 6 settings control text displayed on the form when prompting the user to choose a time to restart their computer -## The title of the window -$WindowTitle = "Restart Required - ${CompanyName}" -## The message displayed to the user when -SysPerf is called. -$SysPerfText = "It looks like your computer isn't performing like it should.`n`nRestarting it will help to resolve some of the problems its been having." -## The message displayed to the user when -OSUpdate is called. -$OSUpdateText = "Good news!`n`nYour computer has recently installed some updates and it needs to be restarted soon." -## Thhe message displayed to the user when -Uptime is called. -$UptimeText = "It looks like your computer has been on for more than $(Get-UptimeDays) days.`n`nIt's probably best to restart soon so it doesn't start causing problems for you." -## This is the message displayed just above the buttons - it should ask the user how they want to proceed -$ProceedText = "When can we make this happen?" -## This is the text for a placebo button. Regardless of whether the user clicks this button or not, -## a reminder has already been created. Clicking the button will just close the form. -## This is simply because I don't want the user to be able to dismiss restarting their -## computer, but I still want them to feel like they're involved and have some control -## over the situation. Automatically reminding them some other time won't hurt anything. -$PlaceboText = "Remind me later" - - -############### NEW SETTINGS ############### - -## The message on the button that immediately restarts the computer -$RebootNowText = "Restart Now" - -## When to begin notifying the user they need to reboot their computer -$StartReminderAt = Get-Date -Hour 9 -Minute 0 -Second 0 - -## When to stop notifying the user to reboot. -## If the next notification to restart is scheduled to happen after this time, -## it will be automatically rescheduled until $StartReminderAt of the following day. -$StopReminderAt = Get-Date -Hour 16 -Minute 50 -Second 0 - -## The amount of time between restart notifications -$ReminderInterval = New-TimeSpan -Hours 2 -Minutes 45 - - -## This is some small amount of time in the future where the user can schedule a reboot. This isn't used often, but is used -## The formula used here will add 20 minutes to the current time and round it to the nearest 5 minute mark. -## I referenced the code by Tony Hinkle in this post: -## https://stackoverflow.com/questions/39728485/rounding-down-minutes-to-the-nearest-10-minutes#39728699 -$ShortTimeFromNow = (Get-Date).AddMinutes(-(((Get-Date).Minute % 5) - 20)) - -## The following 5 settings configure the date and time this script will use to schedule reminders and restarts -## All times will be today's date at the hour, minute, and second specified. -## Specify the business start time. -## This time is used to remind the user to restart their computer. The reminder won't show up until at least the value defined here. -## The $ReminderDelay time will be added to $StartOfBusiness to come up with the time to remind the user to restart their computer. -$StartOfBusiness = Get-Date -Hour 8 -Minute 30 -Second 0 -## Specify the lunch time -## This time is used to schedule a restart all through the week and weekends. -$LunchTime = Get-Date -Hour 12 -Minute 0 -Second 0 -## Specify the afternoon time -## This time is used to schedule a restart only on the weekends and is based on $LunchTime -$AfternoonTime = $LunchTime + (New-TimeSpan -Hours 2 -Minutes 30) -## Specify the close-of-business time. In reality this should be a little bit before the actual close of business time. -## This time is used to remind to restart only during the weekdays. This should be just before everyone starts leaving the office. -$CloseOfBusiness = Get-Date -Hour 16 -Minute 50 -Second 0 -## Specify the late-at-night time -## This time is used to schedule a restart only during the weekdays. You should use a time when users are least likely to work -$LateAtNight = Get-Date -Hour 22 -Minute 0 -Second 0 - -## Specify delay after the $StartOfBusiness when the user will be reminded to restart -## If the user does not restart, this is used to delay the reminder until most people are in the office -## For example: if $StartOfBusiness is 8am, but most people aren't in the office until 8:30am, -## you'll want to specify a value of 30 minutes here. -## They probably don't want to come in and immediately see a reminder to restart their computer. Let them get coffee first :-) -$ReminderDelay = New-TimeSpan -Minutes 40 - -## The next two settings define the week for your customer. -## If their weekend is not Saturday and Sunday, define that here. -## Weekend days -$WeekendDays = @("Saturday","Sunday") -## Week days -$WeekDays = @("Monday","Tuesday","Wednesday","Thursday","Friday") - -## The next two settings define the 2-day reminders and the 1-day reminders. -## On the day this script is run, a reminder is automatically created. -## If the user closes the window or clicks the placebo button, the reminder is already created -## for either the next day, or 2 days from now. -## If you changed the previous 2 settings to specify different weekend and week days, -## you'll probably want to change this setting too. -## The idea behind this is to guide the user to restarting their computer sooner rather than later. -## The default options will push them towards restarting at the end of the work week, but if the -## script runs on the weekend, the reminder won't bother them again until the start of the work week. -## Specify the 2-day reminder days (user will be reminded 2 days after the days in this setting) -$TwoDayReminderDays = @("Monday","Tuesday","Wednesday","Saturday") -## Specify the 1-day reminder days (user will be reminded the day after the days in this setting) -$OneDayReminderDays = @("Thursday","Friday","Sunday") - -#endregion CUSTOMIZATIONS } - -## This is where we do everything needed to either prompt or remind the user to restart their computer -## This will involve copying the script locally, checking for existing reminder priorities, etc... -#region begin PREFLIGHT { - -## Copy this script to $CopyDirectory if it isn't being run from $CopyDirectory -If ( $MyInvocation.PSCommandPath -ne "${CopyDirectory}\${CopyFilename}" ) { Copy-ThisScript } - -## Disallow this script to display to the user before we check the parameters -$AllowDisplay = $false - -## If the last argument is -Task, then make sure we allow this script to display to the user -If ( $args[$args.Count - 1].ToString() -ieq "-Task" ) { $AllowDisplay = $true } - -## If the last argument isn't -Task, then we need to create a scheduled task for 10 seconds from now to run this script -Else { - - Write-Host "No Task" -} - - -#endregion PREFLIGHT } - -## This is where we gather the necessary info and prompt the user to restart -#region begin DISPLAY_FORM - -## Get the nearest time to schedule a restart -#$NearestRestartTime = Get-NearestRestartTime - -## Get the next reminder time -$NextReminderTime = Get-NextReminderTime - -## - -## Display the form -If ( $AllowDisplay ) { Display-Prompt $SysPerfText } - -#endregion DISPLAY_FORM diff --git a/Set-RebootSchedule2.ps1 b/Set-RebootSchedule2.ps1 deleted file mode 100644 index 42ee2ec..0000000 --- a/Set-RebootSchedule2.ps1 +++ /dev/null @@ -1,280 +0,0 @@ -<# - -.SYNOPSIS -Provides friendly messages reminding a user to restart their computer based on events that require it. - -.DESCRIPTION -The Set-RebootSchedule script is called from any computer management software to notify a user of a required restart. -This script accepts several different parameters which change the messages displayed to the user. - -.PARAMETER SysPerf -The -SysPerf parameter will remind the user to restart due to system performance. -This parameter should be called if the computer has had consistently high memory usage, recurring application hangs, or stuck processes. -If this parameter is used it will simply tell the user that a restart is needed to improve overall stability. - -.PARAMETER OSUpdate -The -OSUpdate parameter will remind the user to restart due to operating system updates. - -.PARAMETER Uptime -The -Uptime parameter will remind the user to restart due to long uptimes. -This script does not define the length of time the computer has been on, but will display the number of days to the end user. -If the computer has been on for 10 days and this parameter is used, it will tell the user this computer has been on for 10 days. - -.PARAMETER AllowMinimize -The -AllowMinimize parameter will let the prompt be minimized by the user. -By default, the user is not allowed to minimize the window. - -.EXAMPLE -Set-RebootSchedule -SysPerf -Prompt the user to restart because you've seen problems in multiple areas of the computer. - -.EXAMPLE -Set-RebootSchedule -OSUpdate -Prompt the user to restart because Windows was recently updated. - -.EXAMPLE -Set-RebootSchedule -Uptime -Prompt the user to restart because the computer has been up for a long time. - -.NOTES -Calling this script with no parameters does nothing, the script will just exit without prompting the user for anything. -#> - -## Define parameters - -Param( - [switch]$SysPerf=$false, - [switch]$OSUpdate=$false, - [switch]$Uptime=$false, - [switch]$AllowMinimize=$false -) - -## Get the name of this script -$ScriptName = $MyInvocation.MyCommand.Name - -## Get a list of running PowerShell scripts -$RUnningPSScripts = Get-WmiObject Win32_Process -Filter "Name='powershell.exe'" | Select-Object ProcessId,CommandLine - -## Loop through all other running instances of this script and kill each one that isn't the current instance. -ForEach ( $script in $RUnningPSScripts ) { - $OtherPID = $script.ProcessId - $OtherCMD = $script.CommandLine - - ## Check for other instances of this script that might be running - If ( ($OtherCMD -like "*${ScriptName}*") -and ($OtherPID -ne $PID) ) { - - ## Kill the other instance - Stop-Process -Id $script.ProcessId -Force - } -} - -## Add Windows Forms support to this script -Add-Type -AssemblyName System.Windows.Forms -[System.Windows.Forms.Application]::EnableVisualStyles() - -## Functions and subroutines -#region begin FUNCTIONS { - -## Gets the number of days the system has been up. -Function Get-UptimeDays { - - ## Get a new instance of the Win32_OperatingSystem WMI object - $WMIOS = Get-WmiObject Win32_OperatingSystem - - ## Get the last boot time and convert it to a DateTime value - $LastBootTime = $WMIOS.ConvertToDateTime($WMIOS.LastBootUpTime) - - ## Get the number of days since the last time the system was powered on - [string]$Uptime = (New-TimeSpan -Start $LastBootTime -End $(Get-Date)).Days.ToString() - - Return $Uptime -} - -## Determines whether the logo can be downloaded or not -Function IsLogoDownloadable { - - ## Create a web request - $HTTPRequest = [System.Net.WebRequest]::Create($LogoURL) - - ## Get the response - Try { $HTTPResponse = $HTTPRequest.GetResponse() } - - ## Catch any error2 when trying to connect to the resource (including 404) - Catch [System.Net.WebException] { $HTTPResponse = $_.Exception.Response } - - ## Save the status code - $HTTPStatus = [int]$HTTPResponse.StatusCode - - ## Close the connection, because we're done with it - $HTTPResponse.Close() - - ## Test to make sure we received a status of 200 "OK" from the resource - If ($HTTPStatus -eq 200) { Return $true } - - ## If the status code is anything other than 200, return $false so we can do something else - Else { Return $false } -} - -## Returns the local path of a file downloaded from a URL -Function Get-LogoPath { - - ## Get the file name from $url - $filename = [System.IO.Path]::GetFileName($LogoURL) - - ## Set the destination to download to - $localpath = "${Env:TEMP}\${filename}" - - ## Make sure the file is downloadable - If ( IsLogoDownloadable ) { - - ## Try downloading the file - Try { (New-Object Net.WebClient).DownloadFile($LogoURL, $localpath) } - - ## If you want to handle any download errors, put that code in here - Catch { $_ } - } - - ## Now that the file *may* be downloaded, check to make sure it exists - If ( Test-Path $localpath ) { - - ## Return $localpath to the caller - Return $localpath - } - - ## If $localpath doesn't exist (ie: from a previous execution of this script) then return $false - Else { Return $false } -} - - -## Builds the Windows form to display to the user -Function Display-Prompt([string]$message) { - - ## Set the form's overall parameters - $Form = New-Object System.Windows.Forms.Form - $Form.ClientSize = '400,360' - $Form.Text = $WindowTitle - $Form.TopMost = $true - $Form.MaximizeBox = $false - $Form.MinimizeBox = $AllowMinimize - $Form.FormBorderStyle = 'FixedDialog' - $Form.StartPosition = 'CenterScreen' - - ## Download the logo - $Logo = (Get-LogoPath) - - ## Add a picturebox to the form - If ( $Logo ) { - $pbLogo = New-Object system.Windows.Forms.PictureBox - $pbLogo.Width = $Form.ClientSize.Width - 20 - $pbLogo.Height = 90 - $pbLogo.Anchor = [System.Windows.Forms.AnchorStyles]::None - $pbLogo.Location = New-Object System.Drawing.Point(10,10) - $pbLogo.ImageLocation = $Logo - $pbLogo.SizeMode = [System.Windows.Forms.PictureBoxSizeMode]::CenterImage - $Form.Controls.Add($pbLogo) - } - - ## If the logo isn't available, add label to the form instead of a picturebox - Else { - $lblCompany = New-Object System.Windows.Forms.Label - $lblCompany.Text = $CompanyName - $lblCompany.AutoSize = $false - ## The TextAlign enumerations can be found here: - ## https://docs.microsoft.com/en-us/dotnet/api/system.drawing.contentalignment?view=netframework-2.0 - $lblCompany.TextAlign = 32 - $lblCompany.Width = $Form.ClientSize.Width - 20 - $lblCompany.Height = 60 - $lblCompany.Location = New-Object System.Drawing.Point(10,10) - $lblCompany.Font = 'Microsoft Sans Serif,24,style=Bold' - $Form.Controls.Add($lblCompany) - } - - ## This is the label that contains the reason for the restart - $lblReason = New-Object System.Windows.Forms.Label - $lblReason.Text = $message - $lblReason.AutoSize = $false - $lblReason.TextAlign = 1 - $lblReason.Width = $Form.ClientSize.Width - 50 - $lblReason.Height = 180 - $lblReason.Location = New-Object System.Drawing.Point(25,100) - $lblReason.Font = 'Microsoft Sans Serif,11' - $Form.Controls.Add($lblReason) - - ## This is the label that contains a static message about how to proceed - $lblProceed = New-Object System.Windows.Forms.Label - $lblProceed.Text = $ProceedText - $lblProceed.AutoSize = $true - $lblProceed.TextAlign = 1 - $lblProceed.Location = New-Object System.Drawing.Point(25,280) - $lblProceed.Font = 'Microsoft Sans Serif,11' - $Form.Controls.Add($lblProceed) - - ## This is the button that displays the nearest time to schedule a reboot - $btnRestartNow = New-Object System.Windows.Forms.Button - $btnRestartNow.Text = $RestartNowText - $btnRestartNow.Width = 130 - $btnRestartNow.Height = 30 - $btnRestartNow.Location = New-Object System.Drawing.Point(45,310) - $btnRestartNow.Font = 'Microsoft Sans Serif,11' - $btnRestartNow.Add_Click({ - - ## Restart the computer - Restart-Computer - - ## We're done for now, just close the window. - $Form.Close() - }) - - $Form.AcceptButton = $btmRestartNow - $Form.Controls.Add($btnRestartNow) - - ## This is the placebo button, it just closes the form when clicked. - ## The reminder schedule has already been created, so this button doesn't need to do anything. - $btnCancel = New-Object System.Windows.Forms.Button - $btnCancel.Text = $CancelText - $btnCancel.Width = 130 - $btnCancel.Height = 30 - $btnCancel.Location = New-Object System.Drawing.Point(225,310) - $btnCancel.Font = 'Microsoft Sans Serif,11' - $btnCancel.Add_Click({ $Form.Close() }) - $Form.Controls.Add($btnCancel) - - - [void]$Form.ShowDialog() -} - -#endregion FUNCTIONS } - -## Define custom company name, logo, window title, and messages -#region begin CUSTOMIZATIONS { - -## The following 2 settings are specific to your company -## This is the name of your company. -$CompanyName = "Emberkom" -## This is the URL to your company logo. -## If your company logo cannot be downloaded, $CompanyName will be used instead. -## If the image you specify is larger than 380x90, it will be centered in that area (clipping will occur). -$LogoURL = 'https://emberkom.s3.amazonaws.com/management/scripts/resources/small-web-logo.png' - -## The following 7 settings control text displayed on the form when prompting the user to choose a time to restart their computer -## The title of the window -$WindowTitle = "Restart Required - ${CompanyName}" -## The message displayed to the user when -SysPerf is called. -$SysPerfText = "It looks like your computer isn't performing like it should.`n`nRestarting it will help to resolve some of the problems its been having." -## The message displayed to the user when -OSUpdate is called. -$OSUpdateText = "Good news!`n`nYour computer has recently installed some updates and it needs to be restarted soon." -## The message displayed to the user when -Uptime is called. -$UptimeText = "It looks like your computer has been on for more than $(Get-UptimeDays) days.`n`nIt's probably best to restart soon so it doesn't start causing problems for you." -## This is the message displayed just above the buttons - it should ask the user how they want to proceed -$ProceedText = "Can we make this happen?" -## This is the text for the cancel button. Clicking this button will just close the form -$CancelText = "Remind me later" -## The message on the button that immediately restarts the computer -$RestartNowText = "Restart Now" - -#endregion CUSTOMIZATIONS } - -## Display the form -If ( $SysPerf ) { Display-Prompt $SysPerfText } -ElseIf ( $OSUpdate ) { Display-Prompt $OSUpdateText } -ElseIF ( $Uptime ) { Display-Prompt $UptimeText } diff --git a/Set-WinEvtLog.psm1 b/Set-WinEvtLog.psm1 deleted file mode 100644 index 96121b4..0000000 --- a/Set-WinEvtLog.psm1 +++ /dev/null @@ -1,152 +0,0 @@ -Function global:Set-WinEvtLog { - <# - .SYNOPSIS - Enable/Disable an event log. - .DESCRIPTION - Enable or disable a Windows Event Log using the System.Diagnostics.Eventing.Reader.EventLogConfiguration object. - This function only outputs terminating errors to the console. If you want to see more detail use -verbose - .EXAMPLE - Set-WinEvtLog -Enable -Log "Microsoft-Windows-DNS-Client/Operational" - .EXAMPLE - Set-WinEvtLog -Disable -Log (Get-Content ListOfLogs.txt) - .EXAMPLE - Get-Content ListOfLogs.txt | Set-WinEvtLog -Enable - .PARAMETER Log - The log(s) to modIfy. - .PARAMETER Enable - Enables the log(s). - .PARAMETER Disable - Disables the log(s). - #> - - [CmdletBinding(SupportsShouldProcess=$True,ConfirmImpact='Low')] - param - ( - [Parameter(Mandatory=$True, - ValueFromPipeline=$False, - ValueFromPipelineByPropertyName=$True, - HelpMessage='Which log do you want to enable?')] - [string[]]$Log, - [Parameter(Mandatory=$True, - ValueFromPipelineByPropertyName=$True, - ParameterSetName = 'Enable')] - [Switch]$Enable, - [Parameter(Mandatory=$True, - ValueFromPipelineByPropertyName=$True, - ParameterSetName = 'Disable')] - [Switch]$Disable - ) - - Begin - { - # Keep track of changes made to event logs in a separate file. - $RecordLog = "${Env:MSPDir}\Logs\WinEvtLogs-Enabled.log" - - If ( !(Test-Path -Path $RecordLog) ) - { - # Create the record keeping log file If it doesn't exist. - $NewFile = ((New-Item -Path $RecordLog -ItemType file).name | Out-String) - $NewFile = $NewFile.Trim() - Write-Verbose "$NewFile did not exist and has been created." - } - } - - Process - { - # Make sure Record Keeping is properly configured, otherwise exit. - If ( !($RecordLog) ) - { - Write-Verbose "The record keeping log does not exist, this function will not continue." - Return - } - - # Loop through the name(s) in the $Log variable passed to this function. - ForEach ($name in $Log) - { - # Process the data only If the script should Process data. - If ( $pscmdlet.ShouldProcess($name, 'Enable Log') ) - { - # Load the RecordLog into a variable. - $PreviouslyEnabledLogs = Get-Content $RecordLog - - # Determine whether to Enable or Disable logging of the specIfied log. - Switch ($PSCmdlet.ParameterSetName) - { - 'Enable' { $SetEnable = $True } - 'Disable' { $SetEnable = $False } - } - - # Create a new object for the specIfied log. - $LogObject = New-Object System.Diagnostics.Eventing.Reader.EventLogConfiguration $name - - # Set the variable to determine whether the log has been enabled by this script or not - $IsEnabledByFunction = $False - - # Determine whether or not the log had been enabled by this function. - ForEach ($item in $PreviouslyEnabledLogs) - { If ($item -eq $name) { $IsEnabledByFunction = $True } } - - # Act based on whether the log is already enabled or not. - Switch ($logObject.IsEnabled) - { - $True - { - # Inform user whether this log has been enabled by this function or not. - If ($IsEnabledByFunction) - { Write-Verbose "$name has previously been enabled by this function." } - Else { Write-Verbose "$name has previously been enabled, but not by this function." } - } - - $False - { - # Inform user that this log has been disabled by something other than this function. - If ($IsEnabledByFunction) - { Write-Verbose "$name should already be enabled by this function, but has been disabled by other means." } - } - } - - # ModIfy the log to either enable or disable it. - If ($LogObject.IsEnabled -eq $SetEnable) - { Write-Verbose "$name is already in the desired state." } - Else - { - # Set the log to the desired state. - $LogObject.IsEnabled = $SetEnable - - # Save changes to the log. - $LogObject.SaveChanges() - - # VerIfy the change has been made. - Switch ($LogObject.IsEnabled) - { - $True - { - Write-Verbose "$name has been enabled." - - # Make sure this log wasn't already enabled by this function so we don't write the same name more than once in $RecordLog - If (!($IsEnabledByFunction)) { Add-Content -Path $RecordLog "$name" } - } - - $False - { - # Remove $name from $RecordLog If it was put there by this function. - If ($IsEnabledByFunction) - { - # Clear the contents of $RecordLog - Clear-Content -Path $RecordLog - - # Add each item back in that was already there except for the current $name - ForEach ($filename In $PreviouslyEnabledLogs) - { If ($filename -ne $name) { Add-Content -Path $RecordLog $filename} } - } - Write-Verbose "$name has been disabled." - } - } - } - } - } - } - - end {} -} -Export-ModuleMember -Function Set-WinEvtLog \ No newline at end of file diff --git a/Start-LinuxUpdate.sh b/Start-LinuxUpdate.sh index 714d533..0d6556d 100644 --- a/Start-LinuxUpdate.sh +++ b/Start-LinuxUpdate.sh @@ -6,7 +6,7 @@ function process_debian() apt-get update ## Upgrade packages - apt-get upgrade -y + apt-get upgrade --with-new-pkgs -y ## Remove unused packages apt autoremove diff --git a/Start-PowerShell51Upgrade.bat b/Start-PowerShell51Upgrade.bat deleted file mode 100644 index bf214ff..0000000 --- a/Start-PowerShell51Upgrade.bat +++ /dev/null @@ -1,21 +0,0 @@ -@echo off - -REM Windows Server 2012 x64 -set Win62x64=https://download.microsoft.com/download/6/F/5/6F5FF66C-6775-42B0-86C4-47D41F2DA187/W2K12-KB3191565-x64.msu -set Win62x64File=W2K12-KB3191565-x64.msu - -REM Windows 8.1 x86 -set Win63x86=https://download.microsoft.com/download/6/F/5/6F5FF66C-6775-42B0-86C4-47D41F2DA187/Win8.1-KB3191564-x86.msu -set Win63x86File=Win8.1-KB3191564-x86.msu - -REM Windows 8.1 and Server 2012 R2 x64 -set Win63x64=https://download.microsoft.com/download/6/F/5/6F5FF66C-6775-42B0-86C4-47D41F2DA187/Win8.1AndW2K12R2-KB3191564-x64.msu -set Win63x64File=Win8.1AndW2K12R2-KB3191564-x64.msu - -REM Windows 7 x86 -set Win61x86=https://download.microsoft.com/download/6/F/5/6F5FF66C-6775-42B0-86C4-47D41F2DA187/Win7-KB3191566-x86.zip -set Win61x86File=Win7-KB3191566-x86.zip - -Rem Windows 7 and Server 2008 R2 x64 -set Win61x64=https://download.microsoft.com/download/6/F/5/6F5FF66C-6775-42B0-86C4-47D41F2DA187/Win7AndW2K8R2-KB3191566-x64.zip -set Win61x64File=Win7AndW2K8R2-KB3191566-x64.zip \ No newline at end of file diff --git a/Start-PowerShellUpgrade.ps1 b/Start-PowerShellUpgrade.ps1 deleted file mode 100644 index a8c978e..0000000 --- a/Start-PowerShellUpgrade.ps1 +++ /dev/null @@ -1,74 +0,0 @@ -#Requires -version 2 - -## Get the Windows version information -$WinVersion = "{0}.{1}" -f ([System.Environment]::OSVersion.Version).Major,([System.Environment]::OSVersion.Version).Minor -$WinBuild = ([System.Environment]::OSVersion.Version).Build - -## Get PowerShell version information -$CurrentVersion = "{0}.{1}" -f $PSVersionTable.PSVersion.Major,$PSVersionTable.PSVersion.Minor - -## Check the OS architecture -If ( Test-Path -PathType Container -Path ${env:ProgramFiles(x86)} ) { $Is64bit = $true } Else { $Is64bit = $false } - -## Set a variable to make sure the current Windows version is supported -$InstallSupported = $true - -Switch ( $WinVersion ) { - - ## Windows Vista - "6.0" { - If ( $Is64bit ) { $URL = 'https://download.microsoft.com/download/E/7/6/E76850B8-DA6E-4FF5-8CCE-A24FC513FD16/Windows6.0-KB2506146-x64.msu' } - Else { $URL = 'https://download.microsoft.com/download/E/7/6/E76850B8-DA6E-4FF5-8CCE-A24FC513FD16/Windows6.0-KB2506146-x86.msu' } - $UpgradeVersion = 3.0 - ; break } - - ## Windows 7 - "6.1" { - ## PowerShell 4.0 - If ( $Is64bit ) { $URL = 'https://download.microsoft.com/download/3/D/6/3D61D262-8549-4769-A660-230B67E15B25/Windows6.1-KB2819745-x64-MultiPkg.msu' } - Else { $URL = 'https://download.microsoft.com/download/3/D/6/3D61D262-8549-4769-A660-230B67E15B25/Windows6.1-KB2819745-x86-MultiPkg.msu' } - $UpgradeVersion = 4.0 - ; break } - - ## Windows 8 - #"6.2" {; break } - - ## Windows 8.1 - #"6.3" {; break } - - ## Windows 10 - #"10.0" {; break } - - ## Not Supported - default { $InstallSupported = $false ; break } -} - -## Make sure installation is supported -If ( ($InstallSupported) -and ($CurrentVersion -lt $UpgradeVersion) ) { - - ## Get the file type so we install it the correct way - $FileType = ([System.IO.Path]::GetExtension($File)).ToUpper() - - ## Set the destination file for the downloaded package - $File = "${env:TEMP}\$(Split-Path -Leaf $URL)" - - ## Download the installation package - (New-Object Net.WebClient).DownloadFile($URL,$File) - - If ( Test-Path $File ) { - - ## Get the file extension so we use the correct method to install the update - $FileType = [System.IO.Path]::GetExtension($File) - - ## Write a message so we know what version was upgraded. - Write-Host "Upgrading PowerShell ${CurrentVersion} to version ${UpgradeVersion}" - - ## Install the package - If ( $FileType -ieq "MSU" ) { Start-Process wusa.exe -ArgumentList "${File} /quiet /norestart" -Wait } - If ( $FileType -ieq "MSI" ) { Start-Process msiexec.exe -ArgumentList "/i ${File} /qn /norestart" -Wait } - - ## Delete the downloaded package - Remove-Item -Path $File -Force - } - -} Else { Write-Host "This script cannot upgrade PowerShell on this endpoint." } diff --git a/Tools.ps1 b/Tools.ps1 index c870da7..eb3e268 100644 --- a/Tools.ps1 +++ b/Tools.ps1 @@ -426,4 +426,20 @@ Function Create-Shortcut { Catch { LogErr $_.Exception.Message } } Else { LogMsg "Cannot create shortcut because the target path does not exist" } +} + +# Function to enable or disable a specified log +function Toggle-Log { + param ( + [Parameter(Mandatory = $true)][string]$Name, + [Parameter(Mandatory = $true, ParameterSetName = 'Enable')][switch]$Enable, + [Parameter(Mandatory = $true, ParameterSetName = 'Disable')][switch]$Disable + ) + Try { + $log = New-Object System.Diagnostics.Eventing.Reader.EventLogConfiguration $Name + If ( $Enable ) { $log.IsEnabled = $true } + If ( $Disable ) { $log.IsEnabled = $false } + $log.SaveChanges() + } + Catch { LogMsg $_.Exception.Message } } \ No newline at end of file diff --git a/Uninstall-CCleanerCloud.bat b/Uninstall-CCleanerCloud.bat deleted file mode 100644 index 4fcb9a9..0000000 --- a/Uninstall-CCleanerCloud.bat +++ /dev/null @@ -1,5 +0,0 @@ -@echo off -if exist "%ProgramFiles(x86)%\CCleaner Cloud\uninst.exe" start "" /w "%ProgramFiles(x86)%\CCleaner Cloud\uninst.exe" /S -goto end -if exist "%ProgramFiles%\CCleaner Cloud\uninst.exe" start "" /w "%ProgramFiles%\CCleaner Cloud\uninst.exe" /S -:end \ No newline at end of file diff --git a/Uninstall-Windows10DefaultApps.ps1 b/Uninstall-Windows10DefaultApps.ps1 index 2a6febc..4691ddd 100644 --- a/Uninstall-Windows10DefaultApps.ps1 +++ b/Uninstall-Windows10DefaultApps.ps1 @@ -2,7 +2,7 @@ $AppList = @( ## Office Apps 'Microsoft.Office.Sway', - 'Microsoft.Office.OneNote', + #'Microsoft.Office.OneNote', 'Microsoft.MicrosoftOfficeHub', 'Microsoft.Office.Desktop', diff --git a/Update-RevitServerNetwork.ps1 b/Update-RevitServerNetwork.ps1 deleted file mode 100644 index 4d5b628..0000000 --- a/Update-RevitServerNetwork.ps1 +++ /dev/null @@ -1,6 +0,0 @@ -If ( Test-Path "${Env:SystemDrive}\ProgramData\Autodesk\Revit Server 2016\Config\RSN.ini") -{ - Remove-Item "${Env:SystemDrive}\ProgramData\Autodesk\Revit Server 2016\Config\RSN.ini" - $server = "va01rvt02.dbia.com" - $server | Out-File "${Env:SystemDrive}\ProgramData\Autodesk\Revit Server 2016\Config\RSN.ini" -} \ No newline at end of file diff --git a/Upload-Contents.ps1 b/Upload-Contents.ps1 deleted file mode 100644 index 08ed4bc..0000000 --- a/Upload-Contents.ps1 +++ /dev/null @@ -1,53 +0,0 @@ -param ( - [string]$Path, - [string]$Password, - [int]$SpeedLimit=300, - [switch]$SelfDestruct -) - -## Immediately delete this script from disk, if requested -if ( $SelfDestruct ) { - try { Remove-Item $MyINvocation.InvocationName -Force } - catch { Write-Host "Self destruct failed, killing script!"; exit } } - -## Download required tools -$DOWNLOAD_TOOLS_SCRIPT = "https://emberkom.s3.amazonaws.com/management/scripts/Download-Tools.ps1" -try { Invoke-Expression ((New-Object System.Net.WebClient).DownloadString($DOWNLOAD_TOOLS_SCRIPT)) } -catch { Write-Host "Required tools failed to download!"; exit } - -## Make sure WinSCP exists -$WINSCP = "${Env:Temp}\Emberkom\Tools\winscp.com" -if ( !(Test-Path "${WINSCP}") ) { - if ( Test-Path "${Env:ProgramData}\Emberkom\Tools\winscp.com" ) { - $WINSCP = "${Env:ProgramData}\Emberkom\Tools\winscp.com" - } else { Write-Host "WinSCP does not exist!"; exit } } - -## Prepare WinSCP script file -$HOSTNAME = 'xfer.emberkom.net' -$HOSTKEY = 'ecdsa-sha2-nistp256 256 5iJFeMzLK5Ld7gbLn+NlcYyI+DvbSXB8fmFJLLDh7s0=' -$USERNAME = 'JeQCXVBI80Pj3nL' -#$PASSWORD = '' -$SCRIPT_FILE = [System.IO.Path]::GetTempFileName() -$UPLOAD_SCRIPT = @( - "echo off", - "option batch on", - "option confirm off", - "open sftp://${USERNAME}:${Password}@${HOSTNAME}/ -hostkey=`"${HOSTKEY}`"", - "mkdir `"${Env:ComputerName}`"", - "cd `"${Env:ComputerName}`"", - "mkdir `"${Env:Username}`"", - "cd `"${Env:Username}`"", - "mkdir `"Manual Upload`"", - "cd `"Manual Upload`"", - "put -resume -nopermissions -preservetime -speed=${SpeedLimit} -resumesupport=on -neweronly `"${Path}`"", - "exit") -try { ForEach ($line in $UPLOAD_SCRIPT) { $line | Out-File "${SCRIPT_FILE}" -Append } } -catch { Write-Host "Script file could not be created: ${SCRIPT_FILE}"; exit } - -## Upload the data -try { Start-Process -WindowStyle Hidden "${WINSCP}" -ArgumentList "/script=`"${SCRIPT_FILE}`"" -Wait } -catch { Write-Host "Data transfer failed!" } - -## Delete the script file -try { Remove-Item -Path "${SCRIPT_FILE}" -Force } -catch { Write-Host "Script file could not be deleted: ${SCRIPT_FILE}" } diff --git a/Upload-LiquidFiles.ps1 b/Upload-LiquidFiles.ps1 deleted file mode 100644 index a8c17e9..0000000 --- a/Upload-LiquidFiles.ps1 +++ /dev/null @@ -1,70 +0,0 @@ -param ( - [string]$Path, - [string]$Filedrop = 'https://xfer.emberkom.net/filedrop/cmd', - [string]$From, - [string]$Subject = "Upload from ${Env:COMPUTERNAME}", - [string]$Message = "" -) - -## Build the from address if it isn't specified -If ( !($From) ) -{ - If ( "${Env:USERDOMAIN}" -eq "${Env:COMPUTERNAME}" ) { $From = "${Env:COMPUTERNAME}@localdomain.local".ToLower() } - Else { $From = "${Env:COMPUTERNAME}@${Env:USERDOMAIN}".ToLower() } -} - -## Download required tools -$DOWNLOAD_TOOLS_SCRIPT = "https://emberkom.s3.amazonaws.com/management/scripts/Download-Tools.ps1" -Try { Invoke-Expression ((New-Object System.Net.WebClient).DownloadString($DOWNLOAD_TOOLS_SCRIPT)) } -Catch { Write-Host "Required tools failed to download!" } - -## Get the path to the LiquidFilesCLI application -If ( Test-Path "${Env:ProgramData}\Emberkom\Tools\LiquidFilesCLI.exe" ) { $LFCLI = "${Env:ProgramData}\Emberkom\Tools\LiquidFilesCLI.exe" } -ElseIf ( Test-Path "${Env:AppData}\Emberkom\Tools\LiquidFilesCLI.exe" ) { $LFCLI = "${Env:AppData}\Emberkom\Tools\LiquidFilesCLI.exe" } -Else { Write-Host "Could not find LiquidFilesCLI.exe"; exit } - -## Get the path to the 7za.exe application -If ( Test-Path "${Env:ProgramData}\Emberkom\Tools\7za.exe" ) { $ZIPUTIL = "${Env:ProgramData}\Emberkom\Tools\7za.exe" } -ElseIf ( Test-Path "${Env:AppData}\Emberkom\Tools\7za.exe" ) { $ZIPUTIL = "${Env:AppData}\Emberkom\Tools\7za.exe" } -Else { Write-Host "Could not find 7za.exe"; exit } - -## Set the base args -$ARGS = "filedrop /url:${Filedrop} /from:`"${From}`" /subject:`"${Subject}`" /msg:`"${Message}`" /c:s" - -## Make sure $Path exists -If ( Test-Path $Path ) -{ - ## If $Path is a folder... - If ( Test-Path $Path -PathType Container ) - { - ## Set the archive type - $ARCHIVE_TYPE = "7z" - - ## Set the temporary archive - $TEMP_PATH = [System.IO.Path]::GetTempPath() - $TEMP_FILE = Split-Path $Path -Leaf - $TEMP_ARCHIVE = "${TEMP_PATH}${TEMP_FILE}.${ARCHIVE_TYPE}" - - ## Delete $TEMP_ARCHIVE if it somehow already exists - If ( Test-Path $TEMP_ARCHIVE ) { Remove-Item $TEMP_ARCHIVE -Force } - - ## Compress the folder into the archive - Try { Start-Process -WindowStyle Hidden "${ZIPUTIL}" -ArgumentList "a -r -t${ARCHIVE_TYPE} -w `"${TEMP_ARCHIVE}`" `"${Path}`"" -Wait } - Catch { Write-Host "Could not create ${TEMP_ARCHIVE}"; exit } - - $ARGS = "${ARGS} /f:`"${TEMP_ARCHIVE}`"" - } - - ## If $Path is a file... - ElseIf ( Test-Path $Path -PathType Leaf ) { $ARGS = "${ARGS} /f:`"${Path}`"" } - - ## If $Path doesn't exist... - Else { Write-Host "${Path} doesn't exist!"; exit } -} - -## Upload the file -Try { Start-Process -WindowStyle Hidden "${LFCLI}" -ArgumentList "${ARGS}" -Wait } -Catch { Write-Host "Upload failed!" } - -## Delete the local archive (if it exists) -Finally { If ( Test-Path $TEMP_ARCHIVE ) { Remove-Item $TEMP_ARCHIVE -Force } }