major update

This commit is contained in:
2021-05-24 14:05:59 -04:00
parent 1d882a7ddc
commit e767d39d85
39 changed files with 43 additions and 2272 deletions
-32
View File
@@ -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
-32
View File
@@ -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
}
}
}
}
-117
View File
@@ -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." }
}
-63
View File
@@ -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
-57
View File
@@ -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 }
+1 -1
View File
@@ -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' )
{
-137
View File
@@ -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
-34
View File
@@ -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
+22 -35
View File
@@ -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 }
}
## 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 }
-8
View File
@@ -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
-32
View File
@@ -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
+2 -4
View File
@@ -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 }
-3
View File
@@ -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
-152
View File
@@ -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
-158
View File
@@ -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
View File
View File
View File
View File
View File
View File
-32
View File
@@ -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!" }
-3
View File
@@ -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 }
-31
View File
@@ -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}" }
-678
View File
@@ -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
-280
View File
@@ -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 }
-152
View File
@@ -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
+1 -1
View File
@@ -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
-21
View File
@@ -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
-74
View File
@@ -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." }
+16
View File
@@ -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 }
}
-5
View File
@@ -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
+1 -1
View File
@@ -2,7 +2,7 @@
$AppList = @(
## Office Apps
'Microsoft.Office.Sway',
'Microsoft.Office.OneNote',
#'Microsoft.Office.OneNote',
'Microsoft.MicrosoftOfficeHub',
'Microsoft.Office.Desktop',
-6
View File
@@ -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"
}
-53
View File
@@ -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}" }
-70
View File
@@ -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 } }