diff --git a/Install-DeltekVision.ps1 b/Install-DeltekVision.ps1 new file mode 100644 index 0000000..61b92db --- /dev/null +++ b/Install-DeltekVision.ps1 @@ -0,0 +1,34 @@ +param( + [string]$VisionURL +) + +## Remove the existing shortcut +If ( Test-Path "${Env:UserProfile}\Desktop\Deltek Vision.lnk" ) +{ + Try { Remove-Item -Path "${Env:UserProfile}\Desktop\Deltek Vision.lnk" -Force } + Catch { Write-Output $_.Exception.Message } +} + +## Get the correct path to IE +If ( Test-Path "${Env:ProgramFiles(x86)}" ) { $IEPATH = "${Env:ProgramFiles(x86)}\Internet Explorer\iexplore.exe" } +Else { $IEPATH = "${Env:ProgramFiles(x86)}\Internet Explorer\iexplore.exe" } + +If ( $VisionURL ) +{ + ## Make sure IE exists where we expect it to + If ( Test-Path $IEPATH ) + { + Try + { + $WshShell = New-Object -ComObject WScript.Shell + $Shortcut = $WshShell.CreateShortcut("${Env:UserProfile}\Desktop\Deltek Vision.lnk") + $Shortcut.Arguments = $VisionURL + $Shortcut.Description = "Launch Deltek Vision" + $Shortcut.IconLocation = "${IEPATH}, 0" + $Shortcut.WorkingDirectory = "$(Split-Path -Path $IEPATH -Parent)" + $Shortcut.TargetPath = "${IEPATH}" + $Shortcut.Save() + } + Catch { Write-Output $_.Exception.Message } + } Else { Write-Output "Internet Explorer could not be found: ${IEPATH}" } +} Else { Write-Output "No URL to Deltek Vision was specified!" } diff --git a/Install-LiquidFilesOutlookAgent.ps1 b/Install-LiquidFilesOutlookAgent.ps1 index bf5fee8..a1981d1 100644 --- a/Install-LiquidFilesOutlookAgent.ps1 +++ b/Install-LiquidFilesOutlookAgent.ps1 @@ -7,7 +7,7 @@ If ( $URL ) { Write-Output "LiquidFiles target server: ${URL}" - $INSTALLER_ARGS = 'REGKEYSCRIPT="BaseUrl={0};"' -f $URL + $INSTALLER_ARGS = "REGKEYSCRIPT=`"BaseUrl=${URL};`"" } Else { $INSTALLER_ARGS = '' } diff --git a/PSModule/PSModule-Cleanup.psm1 b/PSModule/PSModule-Cleanup.psm1 new file mode 100644 index 0000000..e69de29 diff --git a/PSModule/PSModule-Create.psm1 b/PSModule/PSModule-Create.psm1 new file mode 100644 index 0000000..e69de29 diff --git a/PSModule/PSModule-Fix.psm1 b/PSModule/PSModule-Fix.psm1 new file mode 100644 index 0000000..e69de29 diff --git a/PSModule/PSModule-Get.psm1 b/PSModule/PSModule-Get.psm1 new file mode 100644 index 0000000..e69de29 diff --git a/PSModule/PSModule-Install.psm1 b/PSModule/PSModule-Install.psm1 new file mode 100644 index 0000000..e69de29 diff --git a/PSModule/PSModule-Remove.psm1 b/PSModule/PSModule-Remove.psm1 new file mode 100644 index 0000000..e69de29 diff --git a/PSModule/PSModule-Set.psm1 b/PSModule/PSModule-Set.psm1 new file mode 100644 index 0000000..167ed97 --- /dev/null +++ b/PSModule/PSModule-Set.psm1 @@ -0,0 +1,152 @@ +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 = "${RecordKeepingDir}\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/PSModule-Start.psm1 b/PSModule/PSModule-Start.psm1 new file mode 100644 index 0000000..e69de29 diff --git a/PSModule/PSModule-Uninstall.psm1 b/PSModule/PSModule-Uninstall.psm1 new file mode 100644 index 0000000..e69de29 diff --git a/PSModule/PSModule-Upload.psm1 b/PSModule/PSModule-Upload.psm1 new file mode 100644 index 0000000..e69de29 diff --git a/PSModule/PSModule.psm1 b/PSModule/PSModule.psm1 new file mode 100644 index 0000000..5ca9690 --- /dev/null +++ b/PSModule/PSModule.psm1 @@ -0,0 +1,150 @@ +#Requires -Version 2.0 + +## Set the MSP name +$MSPName = "Emberkom" + +## Set the name of the environment variable used for locating this module +$MSPEnvVar = 'EKPSM' + +## 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}" + +## Setup the MSP management directory +If ( Test-Path ${Env:ProgramData} ) +{ $RootDir = "${Env:ProgramData}\${MSPName}" } Else { $RootDir = "${Env:SystemDrive}\${MSPName}" } + +$RecordKeepingDir = "${RootDir}\RecordKeeping" +$ScriptsDir = "${RootDir}\Scripts" +$ToolsDir = "${RootDir}\Tools" +$LogsDir = "${RootDir}\Logs" + +## Function to create a directory and return an error if it fails +Function MakeDir +{ + param([string]$Path) + Write-Output "Creating ${Path}" + Try { New-Item -Path $Path -ItemType Directory -Force | Out-Null } + Catch { Write-Output $_.Exception.Message } +} + +## Make sure all the management directories exist +If ( !(Test-Path $RootDir) ) { MakeDir $RootDir } +If ( !(Test-Path $RecordKeepingDir) ) { MakeDir $RecordKeepingDir } +If ( !(Test-Path $ScriptsDir) ) { MakeDir $ScriptsDir } +If ( !(Test-Path $ToolsDir) ) { MakeDir $ToolsDir } +If ( !(Test-Path $LogsDir) ) { MakeDir $LogsDir } + +## Set the path to this module +$ModulePath = "${ScriptDir}\${ModuleName}" + +## Set the path to the module in an environment variable +[System.Environment]::SetEnvironmentVariable("${MSPEnvVar}", "${ModulePath}",[System.EnvironmentVariableTarget]::Machine) + +## Update PATH to include the environment variable, if it's not already present +#$ListOfPaths = [System.Environment]::GetEnvironmentVariable('PATH') +#$SplitListOfPaths = $ListOfPaths.Split(';') +#$ModulePathPresent = $false +#$EnvVarString = '%{0}%' -f $MSPEnvVar +#ForEach ( $path in $SplitListOfPaths ) { If ( $path -eq $EnvVarString ) { $ModulePathPresent = $true } } +#If ( !($ModulePathPresent) ) +#{ +# ## Set the string to update PATH with +# $NewPathString = '{0};{1}' -f $EnvVarString,$ListOfPaths +# [System.Environment]::SetEnvironmentVariable('PATH', "${NewPathString}",[System.EnvironmentVariableTarget]::Machine) +#} + +## 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, $ModulePath) } + 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 + Finaly { $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 $LogDir +Function global:Log +{ + Begin {} + Process {} + End {} +} + +## Import all modules +$ListOfModules = @( + "PSModule-Cleanup", + "PSModule-Create", + "PSModule-Fix", + "PSModule-Get", + "PSModule-Install", + "PSModule-Remove", + "PSModule-Set", + "PSModule-Start", + "PSModule-Uninstall", + "PSModule-Upload" +) +ForEach ($module in $ListOfModules) { Load-Module $module } + +## Make sure this module exports only the functions that should be exported +Export-ModuleMember -Function Log -Variable RecordKeepingDir, ScriptsDir, ToolsDir, LogsDir \ No newline at end of file diff --git a/PSModule/Set-WinEvtLog.psm1 b/PSModule/Set-WinEvtLog.psm1 new file mode 100644 index 0000000..5c99707 Binary files /dev/null and b/PSModule/Set-WinEvtLog.psm1 differ diff --git a/Remove-DeltekVision.ps1 b/Remove-DeltekVision.ps1 index f27e16e..24ac67b 100644 --- a/Remove-DeltekVision.ps1 +++ b/Remove-DeltekVision.ps1 @@ -4,17 +4,8 @@ $APP_PATH = "${Env:UserProfile}\AppData\Local\Apps\2.0" ## Test to make sure it's installed for the current user before continuing If ( Test-Path $APP_PATH ) { - ## Stop the process if it's currently running - Try - { - $Process = Get-Process -Name "DeltekVision" -ErrorAction SilentlyContinue - If ( !($Process -eq $null) ) { Stop-Process -Name $ProcessName -Force } - } - Catch { Write-Output "Deltek Vision is running but couldn't be stopped!"; Exit } - ## Delete the existing installed app Try { Remove-Item $APP_PATH -Recurse -Force } - Catch { Write-Output "There was a problem while deleting the installed version of Deltek Vision!"; Exit } + Catch { Write-Output $_.Exception.Message } - Write-Output "Deltek Vision was successfully uninstalled." -} \ No newline at end of file +} Else { Write-Output "${APP_PATH} does not exist!" } diff --git a/Stop-DeltekVision.ps1 b/Stop-DeltekVision.ps1 new file mode 100644 index 0000000..e91631e --- /dev/null +++ b/Stop-DeltekVision.ps1 @@ -0,0 +1,7 @@ +## Stop the process if it's currently running +$Process = Get-Process -Name "DeltekVision" -ErrorAction SilentlyContinue +If ( $Process -ine $null ) +{ + Try { Stop-Process -Name $Process -Force } + Catch { Write-Output $_.Exception.Message } +} Else { Write-Output "Deltek Vision is not running or it's process could not be found." } \ No newline at end of file diff --git a/Upgrade-DeltekVision.ps1 b/Upgrade-DeltekVision.ps1 deleted file mode 100644 index 9155ba7..0000000 --- a/Upgrade-DeltekVision.ps1 +++ /dev/null @@ -1,40 +0,0 @@ -## Set the path to Deltek Vision -$APP_PATH = "${Env:UserProfile}\AppData\Local\Apps\2.0" - -## Test to make sure it's installed for the current user before continuing -If ( Test-Path $APP_PATH ) -{ - ## Stop the process if it's currently running - Try - { - $Process = Get-Process -Name "DeltekVision" -ErrorAction SilentlyContinue - If ( !($Process -eq $null) ) { Stop-Process -Name $ProcessName -Force } - } - Catch { Write-Output "Deltek Vision is running but couldn't be stopped!"; Exit } - - ## Delete the existing installed app - Try { Remove-Item $APP_PATH -Recurse -Force } - Catch { Write-Output "There was a problem while deleting the installed version of Deltek Vision!"; Exit } - - Write-Output "Deltek Vision was successfully uninstalled." -} - -## Remove the existing shortcut -If ( Test-Path "${Env:UserProfile}\Desktop\Deltek Vision.lnk" ) { Remove-Item -Path "${Env:UserProfile}\Desktop\Deltek Vision.lnk" -Force } - -## Get the correct path to IE -If ( Test-Path "${Env:ProgramFiles(x86)}" ) { $IEPATH = "${Env:ProgramFiles(x86)}\Internet Explorer\iexplore.exe" } -Else { $IEPATH = "${Env:ProgramFiles(x86)}\Internet Explorer\iexplore.exe" } - -## Make sure IE exists where we expect it to -If ( Test-Path $IEPATH ) -{ - $WshShell = New-Object -ComObject WScript.Shell - $Shortcut = $WshShell.CreateShortcut("${Env:UserProfile}\Desktop\Deltek Vision.lnk") - $Shortcut.Arguments = 'https://dbia.deltekfirst.com/DBIAClient/DeltekVision.application' - $Shortcut.Description = "Launch Deltek Vision" - $Shortcut.IconLocation = "${IEPATH}, 0" - $Shortcut.WorkingDirectory = "$(Split-Path -Path $IEPATH -Parent)" - $Shortcut.TargetPath = "${IEPATH}" - $Shortcut.Save() -}