Template: Application Adjustments
Description:
This script can be used as an example or a template for usage with the Application Packaging and Application Adjustment/Shimming functions found on this site.
Language:
Powershell
Usage Type:
Packaging Function
Script Source:
######################################## # Application Adjustments Template # Template Date: 18.8.15.5 # Template By: Sean Huggans ######################################## # Application Specific Variables ######################################## [string]$AppName = "Application X" [int]$PackageType = 2 # 1=Full Package, 2=Adjustments/Shimming Package [string]$PackageVersion = "18.8.15.5" #This may be the same as the application version, but it also may not be depending on your detection method needs. If you need to make changes often, it is recommended to use a dated script version here so that it updates each time. [string]$LogName = "Adjustments.log" ######################################## # No-Touch Variables ######################################## $wmiOS = Get-WmiObject -Class Win32_OperatingSystem; $OS = $wmiOS.Caption $LogDir = "C:\Temp\$($AppName)\$PackageVersion" $LogPath = "$($LogDir)\$($LogName)" switch ($PackageType) { 1 { $LoggingTitle = "$($AppName) Adjustments Script" } 2 { $LoggingTitle = "$($AppName) Installation Script" } default { $LoggingTitle = "$($AppName) Script" } } ######################################## # Functions ######################################## function Log-Action ($Message) { ################################ # Function Version 18.8.10.1 # Function by Sean Huggans ################################ # Function will log the provided message with a timestamp in real time to the configured Log File. # Notes: # - This function is intended for application package scripts, and relies on the $AppName variable to be defined at the start of your script to work. # Usage Examples: # - Log-Action "Success!" # NOTE: Commenting these out, as I have defined them above already #[string]$LogName = $LogName #$LogDir = "C:\Temp\$($AppName)" #$LogPath = "$($LogDir)\$($LogFile)" New-Item -ItemType directory -Path $LogDir -Confirm:$false -Force | out-null "[ $(get-date -Format 'yyyy.MM.dd HH:mm:ss') ] $($Message)" | Out-File $LogPath -Append } function ErrorOut-Script { ######################################## # Error Out the package script # Function Date: 18.8.10.1 # Function By: Sean Huggans ######################################## Log-Action -Message "Script is aborting! See any details above!" # Move the log in case it is used as part of a detection method Move-Item -Path $LogPath "$($LogDir)\Error-Result.log" -force -confirm:$false exit } function Set-AppDirPermissions ($Setting, $DirPath) { ######################################## # Modify Dirrctory Permissions # Function Date: 18.8.10.1 # Function By: Sean Huggans ######################################## # Usage Note 1: function is dependent on the standard logging function being present # Example 1 - "Set-AppDirPermissions -Setting "Modify" -DirPath "C:\Program Files\Application X" if (($Setting) -and ($DirPath)) { try { Log-Action -Message "Setting ""$($Setting)"" permission on ""$($DirPath)""..." $InstallDirObject = Get-Item -LiteralPath $DirPath -ErrorAction Stop $ACL = $InstallDirObject.GetAccessControl() $Rule= New-Object System.Security.AccessControl.FileSystemAccessRule("everyone","$($Setting)","ContainerInherit,Objectinherit","none","Allow") $ACL.SetAccessRule($Rule) $InstallDirObject.SetAccessControl($ACL) Log-Action -Message " - Success!" return $true } catch { Log-Action -Message " - Error!" return $false } } else { Log-Action -Message " - Error! (Incomplete Parameters Passed)" return $false } } # To Ensure the firewall service is on function Enable-WindowsFirewallService { ######################################## # Enable Windows Firewall Service # Function Date: 18.8.10.1 # Function By: Sean Huggans ######################################## Log-Action -Message "Making Sure Windows Firewall is enabled and setting default behaviors..." $ServiceName = $(Get-WmiObject -Class Win32_Service -Property * | where-object {(($_.DisplayName -like "*Windows*") -and ($_.DisplayName -like "*Firewall*"))}).DisplayName try { $Service = Get-WmiObject -Class Win32_Service -filter "displayname='$ServiceName'" -ErrorAction stop $Service.ChangeStartMode("Automatic") | Out-Null if ($Service.State -ne "Running") { $Service.StartService() | Out-Null } Log-Action -Message " - Changed the Startup Type of the '$ServiceName' service to 'Automatic'." return $true } catch { Log-Action -Message " - Error changing the Startup Type of the '$ServiceName' service to 'Automatic'! You will need to do this manually!" return $false } } # To Ensure the firewall is active function Set-WindowsFirewallActive { ######################################## # Set Firewall to Active State # Function Date: 18.8.10.1 # Function By: Sean Huggans ######################################## Log-Action "" try { if ($OS -like "*Windows 10*") { Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled True -Confirm:$false Set-NetFirewallProfile -name Private -DefaultInboundAction Block -Confirm:$false Set-NetFirewallProfile -name Public -DefaultInboundAction Block -Confirm:$false Set-NetFirewallProfile -name Domain -DefaultInboundAction Block -Confirm:$false } else { & netsh advfirewall set privateprofile firewallpolicy blockinbound,allowoutbound | Out-Null & netsh advfirewall set publicprofile firewallpolicy blockinbound,allowoutbound | Out-Null & netsh advfirewall set domainprofile firewallpolicy blockinbound,allowoutbound | Out-Null } Log-Action -Message " - Set default profile behaviors. Default Inbound Action for all profiles is set to Block (default)." return $true } catch { Log-Action -Message " - Error setting default profile behaviors. You will need to set Inbound Action for all profiles to Block (default)!" return $false } } # Note: Detection Method Function is at the bottom of the script - only grab the add function for your installation/adjustment script! # For setting firewall rules function Add-FirewallRule ($RuleName, $RuleType, $ProtocolType, $PortNumber, $ProgramPath) { ######################################## # Create Firewall Rule # Function Date: 18.8.15.4 # Function By: Sean Huggans ######################################## # Usage Note 1: function is dependent on the below 2 lines being present at the beginning of your script, as well as the standard logging function being present $script:wmiOS = Get-WmiObject -Class Win32_OperatingSystem; $script:OS = $wmiOS.Caption # Usage Note 2: Use the Add-Firewall function below in your script, Call the function with the following examples: # - Example 1 (Port): Add-FirewallRule -RuleName "ApplicationX" -RuleType Port -ProtocolType TCP -PortNumber 2233 # - Example 1 (Port Range): Add-FirewallRule -RuleName "ApplicationX" -RuleType Port -ProtocolType UDP -PortNumber 2233-2236 # - Example 2 (Process/Program): Add-FirewallRule -RuleName "ApplicationX" -RuleType Process -ProgramPath "C:\Program Files\Application X\X.exe" #Usage Note 3: It may be benneficial to use the Other firewall related standard functions in order to ensure the firewall is enabled and active prior to calling this function! try { if ($OS -like "*Windows 10*") { switch ($RuleType) { "Port" { if ($PortNumber -notlike "*-*") { New-NetFirewallRule -DisplayName "$($RuleName) ($($ProtocolType) $($PortNumber))" -profile Domain -Direction Inbound -Action Allow -Protocol $($ProtocolType) -LocalPort $PortNumber -ErrorAction Stop | Out-Null } else { Log-Action -Message " - (Info!) Port Number ($PortNumber) is a Range, Attempting to add it now..." New-NetFirewallRule -DisplayName "$($RuleName) ($($ProtocolType) $($PortNumber))" -profile Domain -Direction Inbound -Action Allow -Protocol $($ProtocolType) -LocalPort $PortNumber -ErrorAction Stop | Out-Null } Log-Action -Message " - - Successfully created rule ""$($RuleName) ($($ProtocolType) $($PortNumber))"", Allowing inbound connections on $($ProtocolType) port ""$($PortNumber)""" return $true } "Process" { # Using Split instead get-ItemProperty incase the application is not yet installed when this is called $ProgramSplit = $ProgramPath.Split("\") $ProgramName = $ProgramSplit[$($ProgramSplit.Length -1)] New-NetFirewallRule -DisplayName "$($RuleName) ($($ProgramName))" -profile Domain -Direction Inbound -Program $ProgramPath -Action Allow -ErrorAction Stop | Out-Null Log-Action -Message " - Successfully created rule ""$($RuleName) ($($ProgramName))"", Allowing inbound connections to ""$($ProgramPath)""" return $true } default { Log-Action -Message " - Error: Unknown Rule Type ($($RuleType)) called attempting to create rule ("$($RuleName) ($($ProtocolType))")! Check syntax!" return $false } } } else { switch ($RuleType) { "Port" { if ($PortNumber -notlike "*-*") { & netsh advfirewall firewall add rule name="$($RuleName) ($($ProtocolType) $($PortNumber))" dir=in action=allow protocol=$($ProtocolType) localport=$($PortNumber) Log-Action -Message " - Successfully created rule ""$($RuleName) ($($ProtocolType))"", Allowing inbound connections on $($ProtocolType) port ""$($PortNumber)""" } else { Log-Action -Message " - - (Info!) Port Number ($PortNumber) is a Range, Attempting to add it now..." & netsh advfirewall firewall add rule name="$($RuleName) ($($ProtocolType) $($PortNumber))" dir=in action=allow protocol=$($ProtocolType) localport=$($PortNumber) } Log-Action -Message " - Successfully created rule ""$($RuleName) ($($ProtocolType))"", Allowing inbound connections on $($ProtocolType) port ""$($PortNumber)""" return $true } "Process" { # Using Split instead get-ItemProperty incase the application is not yet installed when this is called $ProgramSplit = $ProgramPath.Split("\") $ProgramName = $ProgramSplit[$($ProgramSplit.Length -1)] & netsh advfirewall firewall add rule name="$($RuleName) ($($ProgramName))" protocol=any enable=yes DIR=In program="$($ProgramPath)" Log-Action -Message " - Successfully created rule ""$($RuleName) ($($ProgramName))"", Allowing inbound connections to ""$($ProgramPath)""" return $true } default { Log-Action -Message " - Error: Unknown Rule Type ($($RuleType)) called attempting to create rule ("$($RuleName) ($($ProtocolType))")! Check syntax!" return $false } } } } catch { Log-Action -Message " - Error creating rule ""$($RuleName) ($($ProtocolType))""!" return $false } } # For Setting Registry Values function Set-RegistryValue ($ValuePath, $ValueName, $ValueData) { ########################################################### # Set-RegistryValue # Function by: Sean Huggans # Function Date: 2018.08.14 ########################################################### # Function will set a registry value, creating the key path if it does not already exist. # Usage Example: Set-RegistryValue -ValuePath "Software\Tests\Test 3" -ValueName "Test Value 4" -ValueData "Test Data REVISED 2" if (($ValuePath -ne "") -and ($ValueName -ne "") -and ($ValueData -ne "")) { $RegistryObject = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $env:COMPUTERNAME) $RegistryObject.CreateSubKey("$($ValuePath)") | Out-Null $RegistryKey = $RegistryObject.OpenSubKey("$($ValuePath)", $true) try { $RegistryKey.SetValue("$($ValueName)", "$($ValueData)", [Microsoft.Win32.RegistryValueKind]::String) | Out-Null Log-Action "Registry Add: $($ValuePath)\$($ValueName) ($($ValueData)): Success!" return $true } catch { Log-Action "Registry Add: $($ValuePath)\$($ValueName) ($($ValueData)): Error!" return $false } } else { Log-Action "Error: Set-RegistryValue was called with missing parameters!" return $false } } ######################################## # Execution Code ######################################## Log-Action -Message "Beginning $($LoggingTitle)!" Log-Action -Message "Package Version: $($PackageVersion)" # Make sure firewall service is enabled and active if (($(Enable-WindowsFirewallService) -eq $true) -and ($(Set-WindowsFirewallActive) -eq $true)) { # In This Example Template, we will call the Firewall Rule creation function for several ports # one at a time. It is possible to run this through a loop if you have a large number of ports # you need to open for a specific application, so keep in mind that that may be easier to # maintain in those cases. For this example, we will call each rule individually and set a total # success variable in order to determine continuation or termination of the script. Log-Action -Message "Adding Firewall Rules..." $AllRulesSuccess = $true if ($(Add-FirewallRule -RuleName "$($AppName)" -RuleType Port -ProtocolType TCP -PortNumber 2233) -ne $true) { $AllRulesSuccess = $false } if ($(Add-FirewallRule -RuleName "$($AppName)" -RuleType Port -ProtocolType UDP -PortNumber 2234-2239) -ne $true) { $AllRulesSuccess = $false } if ($(Add-FirewallRule -RuleName "$($AppName)" -RuleType Process -ProgramPath "C:\Program Files\Application X\X.exe") -ne $true) { $AllRulesSuccess = $false } if ($AllRulesSuccess -eq $true) { # In this example, template we will grant modify access to standard users to a single directory. For applications # requiring this access to many locations, it may again be easier to run this through a loop based on a list kept # in a text file. if ($(Set-AppDirPermissions -Setting "Modify" -DirPath "C:\Program Files\Application X") -eq $true) { if ($(Create-SanfordAppsShortcut -ShortcutName "Application X" -ShortcutPath "C:\Program Files\Application X\Application X\X.exe" -IconFilePath "C:\ProgramData\Sanford Health\Permanent\App Package Resources\Application X\X.ico" -ShortcutType "lnk") -eq $true) { Log-Action "$($LoggingTitle) Completed Successfully!" } else { ErrorOut-Script } } else { ErrorOut-Script } } else { ErrorOut-Script } } else { ErrorOut-Script }
Note: that all applications posted here are posted for use, both commercial and non-commercial, free of charge, and as such are provided as-is, without warranty of any kind whatsoever. visuaFUSION, FMSCUG or any other program listed here's author are not responsible for any damages or shortcomings that result from usage of any of these applications.