Upload from CMSource

This commit is contained in:
2025-09-17 13:39:47 -04:00
parent 63d61fccc1
commit bb47e03eaa
13 changed files with 15658 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -0,0 +1,56 @@
<#
.SYNOPSIS
This script is a template that allows you to extend the toolkit with your own custom functions.
# LICENSE #
PowerShell App Deployment Toolkit - Provides a set of functions to perform common application deployment tasks on Windows.
Copyright (C) 2017 - Sean Lillis, Dan Cunningham, Muhammad Mashwani, Aman Motazedian.
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
.DESCRIPTION
The script is automatically dot-sourced by the AppDeployToolkitMain.ps1 script.
.NOTES
Toolkit Exit Code Ranges:
60000 - 68999: Reserved for built-in exit codes in Deploy-Application.ps1, Deploy-Application.exe, and AppDeployToolkitMain.ps1
69000 - 69999: Recommended for user customized exit codes in Deploy-Application.ps1
70000 - 79999: Recommended for user customized exit codes in AppDeployToolkitExtensions.ps1
.LINK
http://psappdeploytoolkit.com
#>
[CmdletBinding()]
Param (
)
##*===============================================
##* VARIABLE DECLARATION
##*===============================================
# Variables: Script
[string]$appDeployToolkitExtName = 'PSAppDeployToolkitExt'
[string]$appDeployExtScriptFriendlyName = 'App Deploy Toolkit Extensions'
[version]$appDeployExtScriptVersion = [version]'3.8.3'
[string]$appDeployExtScriptDate = '30/09/2020'
[hashtable]$appDeployExtScriptParameters = $PSBoundParameters
##*===============================================
##* FUNCTION LISTINGS
##*===============================================
# <Your custom functions go here>
##*===============================================
##* END FUNCTION LISTINGS
##*===============================================
##*===============================================
##* SCRIPT BODY
##*===============================================
If ($scriptParentPath) {
Write-Log -Message "Script [$($MyInvocation.MyCommand.Definition)] dot-source invoked by [$(((Get-Variable -Name MyInvocation).Value).ScriptName)]" -Source $appDeployToolkitExtName
} Else {
Write-Log -Message "Script [$($MyInvocation.MyCommand.Definition)] invoked directly" -Source $appDeployToolkitExtName
}
##*===============================================
##* END SCRIPT BODY
##*===============================================

View File

@@ -0,0 +1,130 @@
<#
.SYNOPSIS
Displays a graphical console to browse the help for the App Deployment Toolkit functions
# LICENSE #
PowerShell App Deployment Toolkit - Provides a set of functions to perform common application deployment tasks on Windows.
Copyright (C) 2017 - Sean Lillis, Dan Cunningham, Muhammad Mashwani, Aman Motazedian.
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
.DESCRIPTION
Displays a graphical console to browse the help for the App Deployment Toolkit functions
.EXAMPLE
AppDeployToolkitHelp.ps1
.NOTES
.LINK
http://psappdeploytoolkit.com
#>
##*===============================================
##* VARIABLE DECLARATION
##*===============================================
## Variables: Script
[string]$appDeployToolkitHelpName = 'PSAppDeployToolkitHelp'
[string]$appDeployHelpScriptFriendlyName = 'App Deploy Toolkit Help'
[version]$appDeployHelpScriptVersion = [version]'3.8.3'
[string]$appDeployHelpScriptDate = '30/09/2020'
## Variables: Environment
[string]$scriptDirectory = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent
# Dot source the App Deploy Toolkit Functions
. "$scriptDirectory\AppDeployToolkitMain.ps1" -DisableLogging
. "$scriptDirectory\AppDeployToolkitExtensions.ps1"
##*===============================================
##* END VARIABLE DECLARATION
##*===============================================
##*===============================================
##* FUNCTION LISTINGS
##*===============================================
Function Show-HelpConsole {
## Import the Assemblies
Add-Type -AssemblyName 'System.Windows.Forms' -ErrorAction 'Stop'
Add-Type -AssemblyName System.Drawing -ErrorAction 'Stop'
## Form Objects
$HelpForm = New-Object -TypeName 'System.Windows.Forms.Form'
$HelpListBox = New-Object -TypeName 'System.Windows.Forms.ListBox'
$HelpTextBox = New-Object -TypeName 'System.Windows.Forms.RichTextBox'
$InitialFormWindowState = New-Object -TypeName 'System.Windows.Forms.FormWindowState'
## Form Code
$System_Drawing_Size = New-Object -TypeName 'System.Drawing.Size'
$System_Drawing_Size.Height = 665
$System_Drawing_Size.Width = 957
$HelpForm.ClientSize = $System_Drawing_Size
$HelpForm.DataBindings.DefaultDataSourceUpdateMode = 0
$HelpForm.Name = 'HelpForm'
$HelpForm.Text = 'PowerShell App Deployment Toolkit Help Console'
$HelpForm.WindowState = 'Normal'
$HelpForm.ShowInTaskbar = $true
$HelpForm.FormBorderStyle = 'Fixed3D'
$HelpForm.MaximizeBox = $false
$HelpForm.Icon = New-Object -TypeName 'System.Drawing.Icon' -ArgumentList $AppDeployLogoIcon
$HelpListBox.Anchor = 7
$HelpListBox.BorderStyle = 1
$HelpListBox.DataBindings.DefaultDataSourceUpdateMode = 0
$HelpListBox.Font = New-Object -TypeName 'System.Drawing.Font' -ArgumentList ('Microsoft Sans Serif', 9.75, 1, 3, 1)
$HelpListBox.FormattingEnabled = $true
$HelpListBox.ItemHeight = 16
$System_Drawing_Point = New-Object -TypeName 'System.Drawing.Point'
$System_Drawing_Point.X = 0
$System_Drawing_Point.Y = 0
$HelpListBox.Location = $System_Drawing_Point
$HelpListBox.Name = 'HelpListBox'
$System_Drawing_Size = New-Object -TypeName 'System.Drawing.Size'
$System_Drawing_Size.Height = 658
$System_Drawing_Size.Width = 271
$HelpListBox.Size = $System_Drawing_Size
$HelpListBox.Sorted = $true
$HelpListBox.TabIndex = 2
$HelpListBox.add_SelectedIndexChanged({ $HelpTextBox.Text = Get-Help -Name $HelpListBox.SelectedItem -Full | Out-String })
$helpFunctions = Get-Command -CommandType 'Function' | Where-Object { ($_.HelpUri -match 'psappdeploytoolkit') -and ($_.Definition -notmatch 'internal script function') } | Select-Object -ExpandProperty Name
$null = $HelpListBox.Items.AddRange($helpFunctions)
$HelpForm.Controls.Add($HelpListBox)
$HelpTextBox.Anchor = 11
$HelpTextBox.BorderStyle = 1
$HelpTextBox.DataBindings.DefaultDataSourceUpdateMode = 0
$HelpTextBox.Font = New-Object -TypeName 'System.Drawing.Font' -ArgumentList ('Microsoft Sans Serif', 8.5, 0, 3, 1)
$HelpTextBox.ForeColor = [System.Drawing.Color]::FromArgb(255, 0, 0, 0)
$System_Drawing_Point = New-Object -TypeName System.Drawing.Point
$System_Drawing_Point.X = 277
$System_Drawing_Point.Y = 0
$HelpTextBox.Location = $System_Drawing_Point
$HelpTextBox.Name = 'HelpTextBox'
$HelpTextBox.ReadOnly = $True
$System_Drawing_Size = New-Object -TypeName 'System.Drawing.Size'
$System_Drawing_Size.Height = 658
$System_Drawing_Size.Width = 680
$HelpTextBox.Size = $System_Drawing_Size
$HelpTextBox.TabIndex = 1
$HelpTextBox.Text = ''
$HelpForm.Controls.Add($HelpTextBox)
## Save the initial state of the form
$InitialFormWindowState = $HelpForm.WindowState
## Init the OnLoad event to correct the initial state of the form
$HelpForm.add_Load($OnLoadForm_StateCorrection)
## Show the Form
$null = $HelpForm.ShowDialog()
}
##*===============================================
##* END FUNCTION LISTINGS
##*===============================================
##*===============================================
##* SCRIPT BODY
##*===============================================
Write-Log -Message "Load [$appDeployHelpScriptFriendlyName] console..." -Source $appDeployToolkitHelpName
## Show the help console
Show-HelpConsole
Write-Log -Message "[$appDeployHelpScriptFriendlyName] console closed." -Source $appDeployToolkitHelpName
##*===============================================
##* END SCRIPT BODY
##*===============================================

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

@@ -0,0 +1,792 @@
// Date Modified: 30/09/2020
// Version Number: 3.8.3
using System;
using System.Text;
using System.Collections;
using System.ComponentModel;
using System.DirectoryServices;
using System.Security.Principal;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME;
namespace PSADT
{
public class Msi
{
enum LoadLibraryFlags : int
{
DONT_RESOLVE_DLL_REFERENCES = 0x00000001,
LOAD_IGNORE_CODE_AUTHZ_LEVEL = 0x00000010,
LOAD_LIBRARY_AS_DATAFILE = 0x00000002,
LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE = 0x00000040,
LOAD_LIBRARY_AS_IMAGE_RESOURCE = 0x00000020,
LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008
}
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = false)]
static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hFile, LoadLibraryFlags dwFlags);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
static extern int LoadString(IntPtr hInstance, int uID, StringBuilder lpBuffer, int nBufferMax);
// Get MSI exit code message from msimsg.dll resource dll
public static string GetMessageFromMsiExitCode(int errCode)
{
IntPtr hModuleInstance = LoadLibraryEx("msimsg.dll", IntPtr.Zero, LoadLibraryFlags.LOAD_LIBRARY_AS_DATAFILE);
StringBuilder sb = new StringBuilder(255);
LoadString(hModuleInstance, errCode, sb, sb.Capacity + 1);
return sb.ToString();
}
}
public class Explorer
{
private static readonly IntPtr HWND_BROADCAST = new IntPtr(0xffff);
private const int WM_SETTINGCHANGE = 0x1a;
private const int SMTO_ABORTIFHUNG = 0x0002;
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
static extern bool SendNotifyMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
private static extern IntPtr SendMessageTimeout(IntPtr hWnd, int Msg, IntPtr wParam, string lParam, int fuFlags, int uTimeout, IntPtr lpdwResult);
[DllImport("shell32.dll", CharSet = CharSet.Auto, SetLastError = false)]
private static extern int SHChangeNotify(int eventId, int flags, IntPtr item1, IntPtr item2);
public static void RefreshDesktopAndEnvironmentVariables()
{
// Update desktop icons
SHChangeNotify(0x8000000, 0x1000, IntPtr.Zero, IntPtr.Zero);
SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, IntPtr.Zero, null, SMTO_ABORTIFHUNG, 100, IntPtr.Zero);
// Update environment variables
SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, IntPtr.Zero, "Environment", SMTO_ABORTIFHUNG, 100, IntPtr.Zero);
}
}
public sealed class FileVerb
{
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern int LoadString(IntPtr h, int id, StringBuilder sb, int maxBuffer);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern IntPtr LoadLibrary(string s);
public static string GetPinVerb(int VerbId)
{
IntPtr hShell32 = LoadLibrary("shell32.dll");
const int nChars = 255;
StringBuilder Buff = new StringBuilder("", nChars);
LoadString(hShell32, VerbId, Buff, Buff.Capacity);
return Buff.ToString();
}
}
public sealed class IniFile
{
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern int GetPrivateProfileString(string lpAppName, string lpKeyName, string lpDefault, StringBuilder lpReturnedString, int nSize, string lpFileName);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = false)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool WritePrivateProfileString(string lpAppName, string lpKeyName, StringBuilder lpString, string lpFileName);
public static string GetIniValue(string section, string key, string filepath)
{
string sDefault = "";
const int nChars = 1024;
StringBuilder Buff = new StringBuilder(nChars);
GetPrivateProfileString(section, key, sDefault, Buff, Buff.Capacity, filepath);
return Buff.ToString();
}
public static void SetIniValue(string section, string key, StringBuilder value, string filepath)
{
WritePrivateProfileString(section, key, value, filepath);
}
}
public class UiAutomation
{
public enum GetWindow_Cmd : int
{
GW_HWNDFIRST = 0,
GW_HWNDLAST = 1,
GW_HWNDNEXT = 2,
GW_HWNDPREV = 3,
GW_OWNER = 4,
GW_CHILD = 5,
GW_ENABLEDPOPUP = 6
}
public enum ShowWindowEnum
{
Hide = 0,
ShowNormal = 1,
ShowMinimized = 2,
ShowMaximized = 3,
Maximize = 3,
ShowNormalNoActivate = 4,
Show = 5,
Minimize = 6,
ShowMinNoActivate = 7,
ShowNoActivate = 8,
Restore = 9,
ShowDefault = 10,
ForceMinimized = 11
}
public enum UserNotificationState
{
// http://msdn.microsoft.com/en-us/library/bb762533(v=vs.85).aspx
ScreenSaverOrLockedOrFastUserSwitching =1, // A screen saver is displayed, the machine is locked, or a nonactive Fast User Switching session is in progress.
FullScreenOrPresentationModeOrLoginScreen =2, // A full-screen application is running or Presentation Settings are applied. Presentation Settings allow a user to put their machine into a state fit for an uninterrupted presentation, such as a set of PowerPoint slides, with a single click. Also returns this state if machine is at the login screen.
RunningDirect3DFullScreen =3, // A full-screen, exclusive mode, Direct3D application is running.
PresentationMode =4, // The user has activated Windows presentation settings to block notifications and pop-up messages.
AcceptsNotifications =5, // None of the other states are found, notifications can be freely sent.
QuietTime =6, // Introduced in Windows 7. The current user is in "quiet time", which is the first hour after a new user logs into his or her account for the first time.
WindowsStoreAppRunning =7 // Introduced in Windows 8. A Windows Store app is running.
}
// Only for Vista or above
[DllImport("shell32.dll", CharSet = CharSet.Auto, SetLastError = false)]
static extern int SHQueryUserNotificationState(out UserNotificationState pquns);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EnumWindows(EnumWindowsProcD lpEnumFunc, ref IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern int GetWindowTextLength(IntPtr hWnd);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
private static extern IntPtr GetDesktopWindow();
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
private static extern IntPtr GetShellWindow();
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool IsWindowEnabled(IntPtr hWnd);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern bool IsWindowVisible(IntPtr hWnd);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool IsIconic(IntPtr hWnd);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ShowWindow(IntPtr hWnd, ShowWindowEnum flags);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern IntPtr SetActiveWindow(IntPtr hwnd);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern IntPtr SetFocus(IntPtr hWnd);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern bool BringWindowToTop(IntPtr hWnd);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern int GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern int GetCurrentThreadId();
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern bool AttachThreadInput(int idAttach, int idAttachTo, bool fAttach);
[DllImport("user32.dll", EntryPoint = "GetWindowLong", CharSet = CharSet.Auto, SetLastError = false)]
public static extern IntPtr GetWindowLong32(IntPtr hWnd, int nIndex);
[DllImport("user32.dll", EntryPoint = "GetWindowLongPtr", CharSet = CharSet.Auto, SetLastError = false)]
public static extern IntPtr GetWindowLongPtr64(IntPtr hWnd, int nIndex);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern bool EnableMenuItem(IntPtr hMenu, uint uIDEnableItem, uint uEnable);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern IntPtr DestroyMenu(IntPtr hWnd);
public delegate bool EnumWindowsProcD(IntPtr hWnd, ref IntPtr lItems);
public static bool EnumWindowsProc(IntPtr hWnd, ref IntPtr lItems)
{
if (hWnd != IntPtr.Zero)
{
GCHandle hItems = GCHandle.FromIntPtr(lItems);
List<IntPtr> items = hItems.Target as List<IntPtr>;
items.Add(hWnd);
return true;
}
else
{
return false;
}
}
public static List<IntPtr> EnumWindows()
{
try
{
List<IntPtr> items = new List<IntPtr>();
EnumWindowsProcD CallBackPtr = new EnumWindowsProcD(EnumWindowsProc);
GCHandle hItems = GCHandle.Alloc(items);
IntPtr lItems = GCHandle.ToIntPtr(hItems);
EnumWindows(CallBackPtr, ref lItems);
return items;
}
catch (Exception ex)
{
throw new Exception("An error occured during window enumeration: " + ex.Message);
}
}
public static string GetWindowText(IntPtr hWnd)
{
int iTextLength = GetWindowTextLength(hWnd);
if (iTextLength > 0)
{
StringBuilder sb = new StringBuilder(iTextLength);
GetWindowText(hWnd, sb, iTextLength + 1);
return sb.ToString();
}
else
{
return String.Empty;
}
}
public static bool BringWindowToFront(IntPtr windowHandle)
{
bool breturn = false;
if (IsIconic(windowHandle))
{
// Show minimized window because SetForegroundWindow does not work for minimized windows
ShowWindow(windowHandle, ShowWindowEnum.ShowMaximized);
}
int lpdwProcessId;
int windowThreadProcessId = GetWindowThreadProcessId(GetForegroundWindow(), out lpdwProcessId);
int currentThreadId = GetCurrentThreadId();
AttachThreadInput(windowThreadProcessId, currentThreadId, true);
BringWindowToTop(windowHandle);
breturn = SetForegroundWindow(windowHandle);
SetActiveWindow(windowHandle);
SetFocus(windowHandle);
AttachThreadInput(windowThreadProcessId, currentThreadId, false);
return breturn;
}
public static int GetWindowThreadProcessId(IntPtr windowHandle)
{
int processID = 0;
GetWindowThreadProcessId(windowHandle, out processID);
return processID;
}
public static IntPtr GetWindowLong(IntPtr hWnd, int nIndex)
{
if (IntPtr.Size == 4)
{
return GetWindowLong32(hWnd, nIndex);
}
return GetWindowLongPtr64(hWnd, nIndex);
}
public static string GetUserNotificationState()
{
// Only works for Windows Vista or higher
UserNotificationState state;
int returnVal = SHQueryUserNotificationState(out state);
return state.ToString();
}
}
public class QueryUser
{
[DllImport("wtsapi32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern IntPtr WTSOpenServer(string pServerName);
[DllImport("wtsapi32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern void WTSCloseServer(IntPtr hServer);
[DllImport("wtsapi32.dll", CharSet = CharSet.Ansi, SetLastError = false)]
public static extern bool WTSQuerySessionInformation(IntPtr hServer, int sessionId, WTS_INFO_CLASS wtsInfoClass, out IntPtr pBuffer, out int pBytesReturned);
[DllImport("wtsapi32.dll", CharSet = CharSet.Ansi, SetLastError = false)]
public static extern int WTSEnumerateSessions(IntPtr hServer, int Reserved, int Version, out IntPtr pSessionInfo, out int pCount);
[DllImport("wtsapi32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern void WTSFreeMemory(IntPtr pMemory);
[DllImport("winsta.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern int WinStationQueryInformation(IntPtr hServer, int sessionId, int information, ref WINSTATIONINFORMATIONW pBuffer, int bufferLength, ref int returnedLength);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern int GetCurrentProcessId();
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern bool ProcessIdToSessionId(int processId, ref int pSessionId);
public class TerminalSessionData
{
public int SessionId;
public string ConnectionState;
public string SessionName;
public bool IsUserSession;
public TerminalSessionData(int sessionId, string connState, string sessionName, bool isUserSession)
{
SessionId = sessionId;
ConnectionState = connState;
SessionName = sessionName;
IsUserSession = isUserSession;
}
}
public class TerminalSessionInfo
{
public string NTAccount;
public string SID;
public string UserName;
public string DomainName;
public int SessionId;
public string SessionName;
public string ConnectState;
public bool IsCurrentSession;
public bool IsConsoleSession;
public bool IsActiveUserSession;
public bool IsUserSession;
public bool IsRdpSession;
public bool IsLocalAdmin;
public DateTime? LogonTime;
public TimeSpan? IdleTime;
public DateTime? DisconnectTime;
public string ClientName;
public string ClientProtocolType;
public string ClientDirectory;
public int ClientBuildNumber;
}
[StructLayout(LayoutKind.Sequential)]
private struct WTS_SESSION_INFO
{
public Int32 SessionId;
[MarshalAs(UnmanagedType.LPStr)]
public string SessionName;
public WTS_CONNECTSTATE_CLASS State;
}
[StructLayout(LayoutKind.Sequential)]
public struct WINSTATIONINFORMATIONW
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 70)]
private byte[] Reserved1;
public int SessionId;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
private byte[] Reserved2;
public FILETIME ConnectTime;
public FILETIME DisconnectTime;
public FILETIME LastInputTime;
public FILETIME LoginTime;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1096)]
private byte[] Reserved3;
public FILETIME CurrentTime;
}
public enum WINSTATIONINFOCLASS
{
WinStationInformation = 8
}
public enum WTS_CONNECTSTATE_CLASS
{
Active,
Connected,
ConnectQuery,
Shadow,
Disconnected,
Idle,
Listen,
Reset,
Down,
Init
}
public enum WTS_INFO_CLASS
{
SessionId=4,
UserName,
SessionName,
DomainName,
ConnectState,
ClientBuildNumber,
ClientName,
ClientDirectory,
ClientProtocolType=16
}
private static IntPtr OpenServer(string Name)
{
IntPtr server = WTSOpenServer(Name);
return server;
}
private static void CloseServer(IntPtr ServerHandle)
{
WTSCloseServer(ServerHandle);
}
private static IList<T> PtrToStructureList<T>(IntPtr ppList, int count) where T : struct
{
List<T> result = new List<T>();
long pointer = ppList.ToInt64();
int sizeOf = Marshal.SizeOf(typeof(T));
for (int index = 0; index < count; index++)
{
T item = (T) Marshal.PtrToStructure(new IntPtr(pointer), typeof(T));
result.Add(item);
pointer += sizeOf;
}
return result;
}
public static DateTime? FileTimeToDateTime(FILETIME ft)
{
if (ft.dwHighDateTime == 0 && ft.dwLowDateTime == 0)
{
return null;
}
long hFT = (((long) ft.dwHighDateTime) << 32) + ft.dwLowDateTime;
return DateTime.FromFileTime(hFT);
}
public static WINSTATIONINFORMATIONW GetWinStationInformation(IntPtr server, int sessionId)
{
int retLen = 0;
WINSTATIONINFORMATIONW wsInfo = new WINSTATIONINFORMATIONW();
WinStationQueryInformation(server, sessionId, (int) WINSTATIONINFOCLASS.WinStationInformation, ref wsInfo, Marshal.SizeOf(typeof(WINSTATIONINFORMATIONW)), ref retLen);
return wsInfo;
}
public static TerminalSessionData[] ListSessions(string ServerName)
{
IntPtr server = IntPtr.Zero;
if (ServerName == "localhost" || ServerName == String.Empty)
{
ServerName = Environment.MachineName;
}
List<TerminalSessionData> results = new List<TerminalSessionData>();
try
{
server = OpenServer(ServerName);
IntPtr ppSessionInfo = IntPtr.Zero;
int count;
bool _isUserSession = false;
IList<WTS_SESSION_INFO> sessionsInfo;
if (WTSEnumerateSessions(server, 0, 1, out ppSessionInfo, out count) == 0)
{
throw new Win32Exception();
}
try
{
sessionsInfo = PtrToStructureList<WTS_SESSION_INFO>(ppSessionInfo, count);
}
finally
{
WTSFreeMemory(ppSessionInfo);
}
foreach (WTS_SESSION_INFO sessionInfo in sessionsInfo)
{
if (sessionInfo.SessionName != "Services" && sessionInfo.SessionName != "RDP-Tcp")
{
_isUserSession = true;
}
results.Add(new TerminalSessionData(sessionInfo.SessionId, sessionInfo.State.ToString(), sessionInfo.SessionName, _isUserSession));
_isUserSession = false;
}
}
finally
{
CloseServer(server);
}
TerminalSessionData[] returnData = results.ToArray();
return returnData;
}
public static TerminalSessionInfo GetSessionInfo(string ServerName, int SessionId)
{
IntPtr server = IntPtr.Zero;
IntPtr buffer = IntPtr.Zero;
int bytesReturned;
TerminalSessionInfo data = new TerminalSessionInfo();
bool _IsCurrentSessionId = false;
bool _IsConsoleSession = false;
bool _IsUserSession = false;
int currentSessionID = 0;
string _NTAccount = String.Empty;
if (ServerName == "localhost" || ServerName == String.Empty)
{
ServerName = Environment.MachineName;
}
if (ProcessIdToSessionId(GetCurrentProcessId(), ref currentSessionID) == false)
{
currentSessionID = -1;
}
// Get all members of the local administrators group
bool _IsLocalAdminCheckSuccess = false;
List<string> localAdminGroupSidsList = new List<string>();
try
{
DirectoryEntry localMachine = new DirectoryEntry("WinNT://" + ServerName + ",Computer");
string localAdminGroupName = new SecurityIdentifier("S-1-5-32-544").Translate(typeof(NTAccount)).Value.Split('\\')[1];
DirectoryEntry admGroup = localMachine.Children.Find(localAdminGroupName, "group");
object members = admGroup.Invoke("members", null);
string validSidPattern = @"^S-\d-\d+-(\d+-){1,14}\d+$";
foreach (object groupMember in (IEnumerable)members)
{
DirectoryEntry member = new DirectoryEntry(groupMember);
if (member.Name != String.Empty)
{
if (Regex.IsMatch(member.Name, validSidPattern))
{
localAdminGroupSidsList.Add(member.Name);
}
else
{
localAdminGroupSidsList.Add((new NTAccount(member.Name)).Translate(typeof(SecurityIdentifier)).Value);
}
}
}
_IsLocalAdminCheckSuccess = true;
}
catch { }
try
{
server = OpenServer(ServerName);
if (WTSQuerySessionInformation(server, SessionId, WTS_INFO_CLASS.ClientBuildNumber, out buffer, out bytesReturned) == false)
{
return data;
}
int lData = Marshal.ReadInt32(buffer);
data.ClientBuildNumber = lData;
if (WTSQuerySessionInformation(server, SessionId, WTS_INFO_CLASS.ClientDirectory, out buffer, out bytesReturned) == false)
{
return data;
}
string strData = Marshal.PtrToStringAnsi(buffer);
data.ClientDirectory = strData;
if (WTSQuerySessionInformation(server, SessionId, WTS_INFO_CLASS.ClientName, out buffer, out bytesReturned) == false)
{
return data;
}
strData = Marshal.PtrToStringAnsi(buffer);
data.ClientName = strData;
if (WTSQuerySessionInformation(server, SessionId, WTS_INFO_CLASS.ClientProtocolType, out buffer, out bytesReturned) == false)
{
return data;
}
Int16 intData = Marshal.ReadInt16(buffer);
if (intData == 2)
{
strData = "RDP";
data.IsRdpSession = true;
}
else
{
strData = "";
data.IsRdpSession = false;
}
data.ClientProtocolType = strData;
if (WTSQuerySessionInformation(server, SessionId, WTS_INFO_CLASS.ConnectState, out buffer, out bytesReturned) == false)
{
return data;
}
lData = Marshal.ReadInt32(buffer);
data.ConnectState = ((WTS_CONNECTSTATE_CLASS) lData).ToString();
if (WTSQuerySessionInformation(server, SessionId, WTS_INFO_CLASS.SessionId, out buffer, out bytesReturned) == false)
{
return data;
}
lData = Marshal.ReadInt32(buffer);
data.SessionId = lData;
if (WTSQuerySessionInformation(server, SessionId, WTS_INFO_CLASS.DomainName, out buffer, out bytesReturned) == false)
{
return data;
}
strData = Marshal.PtrToStringAnsi(buffer).ToUpper();
data.DomainName = strData;
if (strData != String.Empty)
{
_NTAccount = strData;
}
if (WTSQuerySessionInformation(server, SessionId, WTS_INFO_CLASS.UserName, out buffer, out bytesReturned) == false)
{
return data;
}
strData = Marshal.PtrToStringAnsi(buffer);
data.UserName = strData;
if (strData != String.Empty)
{
data.NTAccount = _NTAccount + "\\" + strData;
string _Sid = (new NTAccount(_NTAccount + "\\" + strData)).Translate(typeof(SecurityIdentifier)).Value;
data.SID = _Sid;
if (_IsLocalAdminCheckSuccess == true)
{
foreach (string localAdminGroupSid in localAdminGroupSidsList)
{
if (localAdminGroupSid == _Sid)
{
data.IsLocalAdmin = true;
break;
}
else
{
data.IsLocalAdmin = false;
}
}
}
}
if (WTSQuerySessionInformation(server, SessionId, WTS_INFO_CLASS.SessionName, out buffer, out bytesReturned) == false)
{
return data;
}
strData = Marshal.PtrToStringAnsi(buffer);
data.SessionName = strData;
if (strData != "Services" && strData != "RDP-Tcp" && data.UserName != String.Empty)
{
_IsUserSession = true;
}
data.IsUserSession = _IsUserSession;
if (strData == "Console")
{
_IsConsoleSession = true;
}
data.IsConsoleSession = _IsConsoleSession;
WINSTATIONINFORMATIONW wsInfo = GetWinStationInformation(server, SessionId);
DateTime? _loginTime = FileTimeToDateTime(wsInfo.LoginTime);
DateTime? _lastInputTime = FileTimeToDateTime(wsInfo.LastInputTime);
DateTime? _disconnectTime = FileTimeToDateTime(wsInfo.DisconnectTime);
DateTime? _currentTime = FileTimeToDateTime(wsInfo.CurrentTime);
TimeSpan? _idleTime = (_currentTime != null && _lastInputTime != null) ? _currentTime.Value - _lastInputTime.Value : TimeSpan.Zero;
data.LogonTime = _loginTime;
data.IdleTime = _idleTime;
data.DisconnectTime = _disconnectTime;
if (currentSessionID == SessionId)
{
_IsCurrentSessionId = true;
}
data.IsCurrentSession = _IsCurrentSessionId;
}
finally
{
WTSFreeMemory(buffer);
buffer = IntPtr.Zero;
CloseServer(server);
}
return data;
}
public static TerminalSessionInfo[] GetUserSessionInfo(string ServerName)
{
if (ServerName == "localhost" || ServerName == String.Empty)
{
ServerName = Environment.MachineName;
}
// Find and get detailed information for all user sessions
// Also determine the active user session. If a console user exists, then that will be the active user session.
// If no console user exists but users are logged in, such as on terminal servers, then select the first logged-in non-console user that is either 'Active' or 'Connected' as the active user.
TerminalSessionData[] sessions = ListSessions(ServerName);
TerminalSessionInfo sessionInfo = new TerminalSessionInfo();
List<TerminalSessionInfo> userSessionsInfo = new List<TerminalSessionInfo>();
string firstActiveUserNTAccount = String.Empty;
bool IsActiveUserSessionSet = false;
foreach (TerminalSessionData session in sessions)
{
if (session.IsUserSession == true)
{
sessionInfo = GetSessionInfo(ServerName, session.SessionId);
if (sessionInfo.IsUserSession == true)
{
if ((firstActiveUserNTAccount == String.Empty) && (sessionInfo.ConnectState == "Active" || sessionInfo.ConnectState == "Connected"))
{
firstActiveUserNTAccount = sessionInfo.NTAccount;
}
if (sessionInfo.IsConsoleSession == true)
{
sessionInfo.IsActiveUserSession = true;
IsActiveUserSessionSet = true;
}
else
{
sessionInfo.IsActiveUserSession = false;
}
userSessionsInfo.Add(sessionInfo);
}
}
}
TerminalSessionInfo[] userSessions = userSessionsInfo.ToArray();
if (IsActiveUserSessionSet == false)
{
foreach (TerminalSessionInfo userSession in userSessions)
{
if (userSession.NTAccount == firstActiveUserNTAccount)
{
userSession.IsActiveUserSession = true;
break;
}
}
}
return userSessions;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,475 @@
<#
.SYNOPSIS
This script performs the installation or uninstallation of an application(s).
# LICENSE #
PowerShell App Deployment Toolkit - Provides a set of functions to perform common application deployment tasks on Windows.
Copyright (C) 2017 - Sean Lillis, Dan Cunningham, Muhammad Mashwani, Aman Motazedian.
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
.DESCRIPTION
The script is provided as a template to perform an install or uninstall of an application(s).
The script either performs an "Install" deployment type or an "Uninstall" deployment type.
The install deployment type is broken down into 3 main sections/phases: Pre-Install, Install, and Post-Install.
The script dot-sources the AppDeployToolkitMain.ps1 script which contains the logic and functions required to install or uninstall an application.
.PARAMETER DeploymentType
The type of deployment to perform. Default is: Install.
.PARAMETER DeployMode
Specifies whether the installation should be run in Interactive, Silent, or NonInteractive mode. Default is: Interactive. Options: Interactive = Shows dialogs, Silent = No dialogs, NonInteractive = Very silent, i.e. no blocking apps. NonInteractive mode is automatically set if it is detected that the process is not user interactive.
.PARAMETER AllowRebootPassThru
Allows the 3010 return code (requires restart) to be passed back to the parent process (e.g. SCCM) if detected from an installation. If 3010 is passed back to SCCM, a reboot prompt will be triggered.
.PARAMETER TerminalServerMode
Changes to "user install mode" and back to "user execute mode" for installing/uninstalling applications for Remote Destkop Session Hosts/Citrix servers.
.PARAMETER DisableLogging
Disables logging to file for the script. Default is: $false.
.EXAMPLE
powershell.exe -Command "& { & '.\Deploy-Application.ps1' -DeployMode 'Silent'; Exit $LastExitCode }"
.EXAMPLE
powershell.exe -Command "& { & '.\Deploy-Application.ps1' -AllowRebootPassThru; Exit $LastExitCode }"
.EXAMPLE
powershell.exe -Command "& { & '.\Deploy-Application.ps1' -DeploymentType 'Uninstall'; Exit $LastExitCode }"
.EXAMPLE
Deploy-Application.exe -DeploymentType "Install" -DeployMode "Silent"
.NOTES
Toolkit Exit Code Ranges:
60000 - 68999: Reserved for built-in exit codes in Deploy-Application.ps1, Deploy-Application.exe, and AppDeployToolkitMain.ps1
69000 - 69999: Recommended for user customized exit codes in Deploy-Application.ps1
70000 - 79999: Recommended for user customized exit codes in AppDeployToolkitExtensions.ps1
.LINK
http://psappdeploytoolkit.com
#>
[CmdletBinding()]
Param (
[Parameter(Mandatory = $false)]
[ValidateSet('Install', 'Uninstall', 'Repair')]
[string]$DeploymentType = 'Install',
[Parameter(Mandatory = $false)]
[ValidateSet('Interactive', 'Silent', 'NonInteractive')]
[string]$DeployMode = 'Interactive',
[Parameter(Mandatory = $false)]
[switch]$AllowRebootPassThru = $false,
[Parameter(Mandatory = $false)]
[switch]$TerminalServerMode = $false,
[Parameter(Mandatory = $false)]
[switch]$DisableLogging = $false
)
Try
{
## Set the script execution policy for this process
Try { Set-ExecutionPolicy -ExecutionPolicy 'ByPass' -Scope 'Process' -Force -ErrorAction 'Stop' }
Catch { }
##*===============================================
##* VARIABLE DECLARATION
##*===============================================
## Variables: Application
[string]$appVendor = 'NCHRI BioPathology Center'
[string]$appName = 'BPC Stars'
[string]$appVersion = ''
[string]$appArch = ''
[string]$appLang = 'EN'
[string]$appRevision = '01'
[string]$appScriptVersion = '1.0.0'
[string]$appScriptDate = '04/02/2021'
[string]$appScriptAuthor = 'John Palmer'
##*===============================================
## Variables: Install Titles (Only set here to override defaults set by the toolkit)
[string]$installName = ''
[string]$installTitle = ''
##* Do not modify section below
#region DoNotModify
## Variables: Exit Code
[int32]$mainExitCode = 0
## Variables: Script
[string]$deployAppScriptFriendlyName = 'Deploy Application'
[version]$deployAppScriptVersion = [version]'3.8.3'
[string]$deployAppScriptDate = '30/09/2020'
[hashtable]$deployAppScriptParameters = $psBoundParameters
## Variables: Environment
If (Test-Path -LiteralPath 'variable:HostInvocation') { $InvocationInfo = $HostInvocation }
Else { $InvocationInfo = $MyInvocation }
[string]$scriptDirectory = Split-Path -Path $InvocationInfo.MyCommand.Definition -Parent
## Dot source the required App Deploy Toolkit Functions
Try
{
[string]$moduleAppDeployToolkitMain = "$scriptDirectory\AppDeployToolkit\AppDeployToolkitMain.ps1"
If (-not (Test-Path -LiteralPath $moduleAppDeployToolkitMain -PathType 'Leaf')) { Throw "Module does not exist at the specified location [$moduleAppDeployToolkitMain]." }
If ($DisableLogging) { . $moduleAppDeployToolkitMain -DisableLogging }
Else { . $moduleAppDeployToolkitMain }
}
Catch
{
If ($mainExitCode -eq 0) { [int32]$mainExitCode = 60008 }
Write-Error -Message "Module [$moduleAppDeployToolkitMain] failed to load: `n$($_.Exception.Message)`n `n$($_.InvocationInfo.PositionMessage)" -ErrorAction 'Continue'
## Exit the script, returning the exit code to SCCM
If (Test-Path -LiteralPath 'variable:HostInvocation') { $script:ExitCode = $mainExitCode; Exit }
Else { Exit $mainExitCode }
}
#endregion
##* Do not modify section above
##*===============================================
##* END VARIABLE DECLARATION
##*===============================================
If ($deploymentType -ine 'Uninstall' -and $deploymentType -ine 'Repair')
{
##*===============================================
##* PRE-INSTALLATION
##*===============================================
[string]$installPhase = 'Pre-Installation'
## Show Welcome Message, close Internet Explorer if required, allow up to 3 deferrals, verify there is enough disk space to complete the install, and persist the prompt
#Show-InstallationWelcome -CloseApps 'iexplore' -AllowDefer -DeferTimes 3 -CheckDiskSpace -PersistPrompt
$ProcessActive = Get-Process FirefoxPOrtable -ErrorAction SilentlyContinue
if ($ProcessActive -eq $null)
{
Write-Log "BPC Stars is not currently running, continuing with the installation."
}
else
{
Write-Log "BPC Stars is currently running, prompting the user to close the application before continuing."
Show-InstallationWelcome -CloseApps 'FirefoxPOrtable,firefox' -AllowDefer -DeferTimes 3 -CheckDiskSpace -PersistPrompt
}
## Show Progress Message (with the default message)
#Show-InstallationProgress
## <Perform Pre-Installation tasks here>
## Remove any of the old BPC Stars Shortcuts from the Public Desktop ##
$OldProdLnk = Test-Path "C:\Users\Public\Desktop\STARS PROD.lnk"
$OldUAT2lnk = Test-Path "C:\Users\Public\Desktop\STARS UAT2.lnk"
$OldUAT1lnk = Test-Path "C:\Users\Public\Desktop\STARS UAT1.lnk"
$OldBreaKFix = Test-Path "C:\Users\Public\Desktop\Breakfix.lnk"
$OldTraining = Test-Path "C:\Users\Public\Desktop\STARS_Training Portable.lnk"
$OldProdPort = Test-Path "C:\Users\Public\Desktop\STARS PROD Portable.lnk"
If ($OldProdLnk -eq "True")
{
Write-Log "Removing Stars Prod Public Desktop Shortcut."
Remove-File -Path "C:\Users\Public\Desktop\STARS PROD.lnk" -Recurse
}
If ($OldUAT2lnk -eq "True")
{
Write-Log "Removing Stars UAT2 Public Desktop Shortcut."
Remove-File -Path "C:\Users\Public\Desktop\STARS UAT2.lnk" -Recurse
}
If ($OldUAT1lnk -eq "True")
{
Write-Log "Removing Stars UAT1 Public Desktop Shortcut."
Remove-File -Path "C:\Users\Public\Desktop\STARS UAT1.lnk" -Recurse
}
If ($OldBreaKFix -eq "True")
{
Write-Log "Removing Stars UAT1 Public Desktop Shortcut."
Remove-File -Path "C:\Users\Public\Desktop\STARS UAT1.lnk" -Recurse
}
If ($OldTraining -eq "True")
{
Write-Log "Removing Stars UAT1 Public Desktop Shortcut."
Remove-File -Path "C:\Users\Public\Desktop\STARS_Training Portable.lnk" -Recurse
}
if ($OldProdPort -eq "True")
{
Write-Log "Removing Stars UAT1 Public Desktop Shortcut."
Remove-File -Path "C:\Users\Public\Desktop\STARS PROD Portable.lnk" -Recurse
}
## Remove any of the old BPC Stars Shortcuts from the Users Desktop ##
$OldProdLnkUser = Test-Path "$env:userprofile\Desktop\STARS PROD.lnk"
$OldUAT2lnkUser = Test-Path "$env:userprofile\Desktop\STARS UAT2.lnk"
$OldUAT1lnkUser = Test-Path "$env:userprofile\Desktop\STARS UAT1.lnk"
$OldBreaKFixUser = Test-Path "$env:userprofile\Desktop\Breakfix.lnk"
$OldTrainingUser = Test-Path "$env:userprofile\Desktop\STARS_Training Portable.lnk"
$OldProdPort = Test-Path "$env:USERPROFILE\Desktop\STARS PROD Portable.lnk"
If ($OldProdLnkUser -eq "True")
{
Write-Log "Removing Old BCP Stars Dekstop Shortcuts."
Remove-File -Path "$env:userprofile\Desktop\STARS PROD.lnk" -Recurse
}
If ($OldUAT2lnkUser -eq "True")
{
Write-Log "Removing Old BCP Stars Dekstop Shortcuts."
Remove-File -Path "$env:userprofile\Desktop\STARS UAT2.lnk" -Recurse
}
If ($OldUAT1lnkUser -eq "True")
{
Write-Log "Removing Old BCP Stars Dekstop Shortcuts."
Remove-File -Path "$env:userprofile\Desktop\STARS UAT1.lnk" -Recurse
}
If ($OldBreaKFixUser -eq "True")
{
Write-Log "Removing Old BCP Stars Dekstop Shortcuts."
Remove-File -Path "$env:userprofile\Desktop\STARS UAT1.lnk" -Recurse
}
If ($OldTrainingUser -eq "True")
{
Write-Log "Removing Old BCP Stars Dekstop Shortcuts."
Remove-File -Path "$env:userprofile\Desktop\STARS_Training Portable.lnk" -Recurse
}
If ($OldProdPort -eq "True")
{
Write-Log "Removing Old BCP Stars Dekstop Shortcuts."
Remove-File -Path "$env:userprofile\Desktop\STARS PROD Portable" -Recurse
}
## Remove the previous BCP Stars Install ##
$OldStars = Test-Path "C:\Program Files (x86)\STARS\"
If ($OldStars -eq "True")
{
Write-Log "A version of BPC Stars is already installed, removing it and replacing it with the latest."
Remove-File -Path "C:\Program Files (x86)\STARS\" -Recurse
}
##*===============================================
##* INSTALLATION
##*===============================================
[string]$installPhase = 'Installation'
## Handle Zero-Config MSI Installations
If ($useDefaultMsi)
{
[hashtable]$ExecuteDefaultMSISplat = @{ Action = 'Install'; Path = $defaultMsiFile }; If ($defaultMstFile) { $ExecuteDefaultMSISplat.Add('Transform', $defaultMstFile) }
Execute-MSI @ExecuteDefaultMSISplat; If ($defaultMspFiles) { $defaultMspFiles | ForEach-Object { Execute-MSI -Action 'Patch' -Path $_ } }
}
## <Perform Installation tasks here>
New-Folder -Path "C:\Program Files (x86)\STARS\FireFoxPortable"
Copy-Item -Path "$dirFiles\FireFox Portable 75\*" -Destination "C:\Program Files (x86)\STARS\FireFoxPortable" -Recurse
## Copy the Icons to the Public Desktop ##
Write-Log "Copy the new shortcuts to the Public Desktop"
Copy-Item -Path "C:\Program Files (x86)\STARS\FireFoxPortable\*.lnk" -Destination "C:\Users\Public\Desktop"
Refresh-Desktop
##*===============================================
##* POST-INSTALLATION
##*===============================================
[string]$installPhase = 'Post-Installation'
## <Perform Post-Installation tasks here>
<# Legacy Block, unnecessary complication.
## Create a custom registry entry so that the application can be detected from SCCM ##
$HKLMCustomApp = "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\BPC STARS"
New-Item -Path $HKLMCustomApp
Set-ItemProperty -Path $HKLMCustomApp -Name DisplayName "BPC STARS (Only Uninstall from Software Center)"
Set-ItemProperty -Path $HKLMCustomApp -Name DisplayIcon "C:\Program Files (x86)\STARS\FireFoxPortable 75\firefox_0000.ico"
Set-ItemProperty -Path $HKLMCustomApp -Name UninstallString "C:\Program Files (x86\STARS\FireFoxPortable 75\firefoxportable.exe"
Set-ItemProperty -Path $HKLMCustomApp -Name DisplayVersion "75.0"
Set-ItemProperty -Path $HKLMCustomApp -Name Publisher "NCHRI Biopathology Center"
$Name = "NoModify"
$value = "1"
IF (!(Test-Path $HKLMCustomApp))
{
New-Item -Path $HKLMCustomApp -Force | Out-Null
New-ItemProperty -Path $HKLMCustomApp -Name $name -Value $value -PropertyType DWORD -Force | Out-Null
}
ELSE
{
New-ItemProperty -Path $HKLMCustomApp -Name $name -Value $value -PropertyType DWORD -Force | Out-Null
}
#>
## Set the Permissions on the Firefox Portable folder. ##
CACLS "C:\Program Files (x86)\STARS\FireFoxPortable" /e /t /p Users:f
## Display a message at the end of the install
If (-not $useDefaultMsi)
{
#Show-InstallationPrompt -Message 'You can customize text to appear at the end of an install or remove it completely for unattended installations.' -ButtonRightText 'OK' -Icon Information -NoWait }
}
}
ElseIf ($deploymentType -ieq 'Uninstall')
{
##*===============================================
##* PRE-UNINSTALLATION
##*===============================================
[string]$installPhase = 'Pre-Uninstallation'
## Show Welcome Message, close Internet Explorer with a 60 second countdown before automatically closing
Show-InstallationWelcome -CloseApps 'FirefoxPortable' -CloseAppsCountdown 60
## Show Progress Message (with the default message)
Show-InstallationProgress
## <Perform Pre-Uninstallation tasks here>
##*===============================================
##* UNINSTALLATION
##*===============================================
[string]$installPhase = 'Uninstallation'
## Handle Zero-Config MSI Uninstallations
If ($useDefaultMsi)
{
[hashtable]$ExecuteDefaultMSISplat = @{ Action = 'Uninstall'; Path = $defaultMsiFile }; If ($defaultMstFile) { $ExecuteDefaultMSISplat.Add('Transform', $defaultMstFile) }
Execute-MSI @ExecuteDefaultMSISplat
}
# <Perform Uninstallation tasks here>
## Removes FireFox Portable ##
Remove-File -Path "C:\Program Files (x86)\STARS\" -Recurse
##*===============================================
##* POST-UNINSTALLATION
##*===============================================
[string]$installPhase = 'Post-Uninstallation'
## <Perform Post-Uninstallation tasks here>
# Remove the Shortcuts ##
## Remove any of the old BPC Stars Shortcuts from the Public Desktop ##
$ProdLnk = Test-Path "C:\Users\Public\Desktop\STARS PROD.lnk"
$Traning = Test-Path "C:\Users\Public\Desktop\STARS Training.lnk"
If ($ProdLnk -eq "True")
{
Remove-Item -Path "C:\Users\Public\Desktop\STARS PROD.lnk" -Recurse
}
If ($Training -eq "True")
{
Remove-Item -Path "C:\Users\Public\Desktop\STARS Training.lnk" -Recurse
}
## Remove any of the old BPC Stars Shortcuts from the Users Desktop ##
$ProdLnkUser = Test-Path "$env:userprofile\Desktop\STARS PROD.lnk"
$TraningUser = Test-Path "$env:userprofile\Desktop\STARS Training.lnk"
If ($ProdLnkUser -eq "True")
{
Remove-File -Path "$env:userprofile\Desktop\STARS PROD.lnk" -Recurse
}
If ($TrainingUser -eq "True")
{
Remove-File -Path "$env:userprofile\Desktop\STARS Training.lnk" -Recurse
}
}
ElseIf ($deploymentType -ieq 'Repair')
{
##*===============================================
##* PRE-REPAIR
##*===============================================
[string]$installPhase = 'Pre-Repair'
## Show Progress Message (with the default message)
Show-InstallationProgress
## <Perform Pre-Repair tasks here>
##*===============================================
##* REPAIR
##*===============================================
[string]$installPhase = 'Repair'
## Handle Zero-Config MSI Repairs
If ($useDefaultMsi)
{
[hashtable]$ExecuteDefaultMSISplat = @{ Action = 'Repair'; Path = $defaultMsiFile; }; If ($defaultMstFile) { $ExecuteDefaultMSISplat.Add('Transform', $defaultMstFile) }
Execute-MSI @ExecuteDefaultMSISplat
}
# <Perform Repair tasks here>
##*===============================================
##* POST-REPAIR
##*===============================================
[string]$installPhase = 'Post-Repair'
## <Perform Post-Repair tasks here>
}
##*===============================================
##* END SCRIPT BODY
##*===============================================
## Call the Exit-Script function to perform final cleanup operations
Exit-Script -ExitCode $mainExitCode
}
Catch
{
[int32]$mainExitCode = 60001
[string]$mainErrorMessage = "$(Resolve-Error)"
Write-Log -Message $mainErrorMessage -Severity 3 -Source $deployAppScriptFriendlyName
Show-DialogBox -Text $mainErrorMessage -Icon 'Stop'
Exit-Script -ExitCode $mainExitCode
}

View File

@@ -0,0 +1,475 @@
<#
.SYNOPSIS
This script performs the installation or uninstallation of an application(s).
# LICENSE #
PowerShell App Deployment Toolkit - Provides a set of functions to perform common application deployment tasks on Windows.
Copyright (C) 2017 - Sean Lillis, Dan Cunningham, Muhammad Mashwani, Aman Motazedian.
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
.DESCRIPTION
The script is provided as a template to perform an install or uninstall of an application(s).
The script either performs an "Install" deployment type or an "Uninstall" deployment type.
The install deployment type is broken down into 3 main sections/phases: Pre-Install, Install, and Post-Install.
The script dot-sources the AppDeployToolkitMain.ps1 script which contains the logic and functions required to install or uninstall an application.
.PARAMETER DeploymentType
The type of deployment to perform. Default is: Install.
.PARAMETER DeployMode
Specifies whether the installation should be run in Interactive, Silent, or NonInteractive mode. Default is: Interactive. Options: Interactive = Shows dialogs, Silent = No dialogs, NonInteractive = Very silent, i.e. no blocking apps. NonInteractive mode is automatically set if it is detected that the process is not user interactive.
.PARAMETER AllowRebootPassThru
Allows the 3010 return code (requires restart) to be passed back to the parent process (e.g. SCCM) if detected from an installation. If 3010 is passed back to SCCM, a reboot prompt will be triggered.
.PARAMETER TerminalServerMode
Changes to "user install mode" and back to "user execute mode" for installing/uninstalling applications for Remote Destkop Session Hosts/Citrix servers.
.PARAMETER DisableLogging
Disables logging to file for the script. Default is: $false.
.EXAMPLE
powershell.exe -Command "& { & '.\Deploy-Application.ps1' -DeployMode 'Silent'; Exit $LastExitCode }"
.EXAMPLE
powershell.exe -Command "& { & '.\Deploy-Application.ps1' -AllowRebootPassThru; Exit $LastExitCode }"
.EXAMPLE
powershell.exe -Command "& { & '.\Deploy-Application.ps1' -DeploymentType 'Uninstall'; Exit $LastExitCode }"
.EXAMPLE
Deploy-Application.exe -DeploymentType "Install" -DeployMode "Silent"
.NOTES
Toolkit Exit Code Ranges:
60000 - 68999: Reserved for built-in exit codes in Deploy-Application.ps1, Deploy-Application.exe, and AppDeployToolkitMain.ps1
69000 - 69999: Recommended for user customized exit codes in Deploy-Application.ps1
70000 - 79999: Recommended for user customized exit codes in AppDeployToolkitExtensions.ps1
.LINK
http://psappdeploytoolkit.com
#>
[CmdletBinding()]
Param (
[Parameter(Mandatory = $false)]
[ValidateSet('Install', 'Uninstall', 'Repair')]
[string]$DeploymentType = 'Install',
[Parameter(Mandatory = $false)]
[ValidateSet('Interactive', 'Silent', 'NonInteractive')]
[string]$DeployMode = 'Interactive',
[Parameter(Mandatory = $false)]
[switch]$AllowRebootPassThru = $false,
[Parameter(Mandatory = $false)]
[switch]$TerminalServerMode = $false,
[Parameter(Mandatory = $false)]
[switch]$DisableLogging = $false
)
Try
{
## Set the script execution policy for this process
Try { Set-ExecutionPolicy -ExecutionPolicy 'ByPass' -Scope 'Process' -Force -ErrorAction 'Stop' }
Catch { }
##*===============================================
##* VARIABLE DECLARATION
##*===============================================
## Variables: Application
[string]$appVendor = 'NCHRI BioPathology Center'
[string]$appName = 'BPC Stars'
[string]$appVersion = ''
[string]$appArch = ''
[string]$appLang = 'EN'
[string]$appRevision = '01'
[string]$appScriptVersion = '1.0.0'
[string]$appScriptDate = '04/02/2021'
[string]$appScriptAuthor = 'John Palmer'
##*===============================================
## Variables: Install Titles (Only set here to override defaults set by the toolkit)
[string]$installName = ''
[string]$installTitle = ''
##* Do not modify section below
#region DoNotModify
## Variables: Exit Code
[int32]$mainExitCode = 0
## Variables: Script
[string]$deployAppScriptFriendlyName = 'Deploy Application'
[version]$deployAppScriptVersion = [version]'3.8.3'
[string]$deployAppScriptDate = '30/09/2020'
[hashtable]$deployAppScriptParameters = $psBoundParameters
## Variables: Environment
If (Test-Path -LiteralPath 'variable:HostInvocation') { $InvocationInfo = $HostInvocation }
Else { $InvocationInfo = $MyInvocation }
[string]$scriptDirectory = Split-Path -Path $InvocationInfo.MyCommand.Definition -Parent
## Dot source the required App Deploy Toolkit Functions
Try
{
[string]$moduleAppDeployToolkitMain = "$scriptDirectory\AppDeployToolkit\AppDeployToolkitMain.ps1"
If (-not (Test-Path -LiteralPath $moduleAppDeployToolkitMain -PathType 'Leaf')) { Throw "Module does not exist at the specified location [$moduleAppDeployToolkitMain]." }
If ($DisableLogging) { . $moduleAppDeployToolkitMain -DisableLogging }
Else { . $moduleAppDeployToolkitMain }
}
Catch
{
If ($mainExitCode -eq 0) { [int32]$mainExitCode = 60008 }
Write-Error -Message "Module [$moduleAppDeployToolkitMain] failed to load: `n$($_.Exception.Message)`n `n$($_.InvocationInfo.PositionMessage)" -ErrorAction 'Continue'
## Exit the script, returning the exit code to SCCM
If (Test-Path -LiteralPath 'variable:HostInvocation') { $script:ExitCode = $mainExitCode; Exit }
Else { Exit $mainExitCode }
}
#endregion
##* Do not modify section above
##*===============================================
##* END VARIABLE DECLARATION
##*===============================================
If ($deploymentType -ine 'Uninstall' -and $deploymentType -ine 'Repair')
{
##*===============================================
##* PRE-INSTALLATION
##*===============================================
[string]$installPhase = 'Pre-Installation'
## Show Welcome Message, close Internet Explorer if required, allow up to 3 deferrals, verify there is enough disk space to complete the install, and persist the prompt
#Show-InstallationWelcome -CloseApps 'iexplore' -AllowDefer -DeferTimes 3 -CheckDiskSpace -PersistPrompt
$ProcessActive = Get-Process FirefoxPOrtable -ErrorAction SilentlyContinue
if ($ProcessActive -eq $null)
{
Write-Log "BPC Stars is not currently running, continuing with the installation."
}
else
{
Write-Log "BPC Stars is currently running, prompting the user to close the application before continuing."
Show-InstallationWelcome -CloseApps 'FirefoxPOrtable,firefox' -AllowDefer -DeferTimes 3 -CheckDiskSpace -PersistPrompt
}
## Show Progress Message (with the default message)
#Show-InstallationProgress
## <Perform Pre-Installation tasks here>
## Remove any of the old BPC Stars Shortcuts from the Public Desktop ##
$OldProdLnk = Test-Path "C:\Users\Public\Desktop\STARS PROD.lnk"
$OldUAT2lnk = Test-Path "C:\Users\Public\Desktop\STARS UAT2.lnk"
$OldUAT1lnk = Test-Path "C:\Users\Public\Desktop\STARS UAT1.lnk"
$OldBreaKFix = Test-Path "C:\Users\Public\Desktop\Breakfix.lnk"
$OldTraining = Test-Path "C:\Users\Public\Desktop\STARS_Training Portable.lnk"
$OldProdPort = Test-Path "C:\Users\Public\Desktop\STARS PROD Portable.lnk"
If ($OldProdLnk -eq "True")
{
Write-Log "Removing Stars Prod Public Desktop Shortcut."
Remove-File -Path "C:\Users\Public\Desktop\STARS PROD.lnk" -Recurse
}
If ($OldUAT2lnk -eq "True")
{
Write-Log "Removing Stars UAT2 Public Desktop Shortcut."
Remove-File -Path "C:\Users\Public\Desktop\STARS UAT2.lnk" -Recurse
}
If ($OldUAT1lnk -eq "True")
{
Write-Log "Removing Stars UAT1 Public Desktop Shortcut."
Remove-File -Path "C:\Users\Public\Desktop\STARS UAT1.lnk" -Recurse
}
If ($OldBreaKFix -eq "True")
{
Write-Log "Removing Stars UAT1 Public Desktop Shortcut."
Remove-File -Path "C:\Users\Public\Desktop\STARS UAT1.lnk" -Recurse
}
If ($OldTraining -eq "True")
{
Write-Log "Removing Stars UAT1 Public Desktop Shortcut."
Remove-File -Path "C:\Users\Public\Desktop\STARS_Training Portable.lnk" -Recurse
}
if ($OldProdPort -eq "True")
{
Write-Log "Removing Stars UAT1 Public Desktop Shortcut."
Remove-File -Path "C:\Users\Public\Desktop\STARS PROD Portable.lnk" -Recurse
}
## Remove any of the old BPC Stars Shortcuts from the Users Desktop ##
$OldProdLnkUser = Test-Path "$env:userprofile\Desktop\STARS PROD.lnk"
$OldUAT2lnkUser = Test-Path "$env:userprofile\Desktop\STARS UAT2.lnk"
$OldUAT1lnkUser = Test-Path "$env:userprofile\Desktop\STARS UAT1.lnk"
$OldBreaKFixUser = Test-Path "$env:userprofile\Desktop\Breakfix.lnk"
$OldTrainingUser = Test-Path "$env:userprofile\Desktop\STARS_Training Portable.lnk"
$OldProdPort = Test-Path "$env:USERPROFILE\Desktop\STARS PROD Portable.lnk"
If ($OldProdLnkUser -eq "True")
{
Write-Log "Removing Old BCP Stars Dekstop Shortcuts."
Remove-File -Path "$env:userprofile\Desktop\STARS PROD.lnk" -Recurse
}
If ($OldUAT2lnkUser -eq "True")
{
Write-Log "Removing Old BCP Stars Dekstop Shortcuts."
Remove-File -Path "$env:userprofile\Desktop\STARS UAT2.lnk" -Recurse
}
If ($OldUAT1lnkUser -eq "True")
{
Write-Log "Removing Old BCP Stars Dekstop Shortcuts."
Remove-File -Path "$env:userprofile\Desktop\STARS UAT1.lnk" -Recurse
}
If ($OldBreaKFixUser -eq "True")
{
Write-Log "Removing Old BCP Stars Dekstop Shortcuts."
Remove-File -Path "$env:userprofile\Desktop\STARS UAT1.lnk" -Recurse
}
If ($OldTrainingUser -eq "True")
{
Write-Log "Removing Old BCP Stars Dekstop Shortcuts."
Remove-File -Path "$env:userprofile\Desktop\STARS_Training Portable.lnk" -Recurse
}
If ($OldProdPort -eq "True")
{
Write-Log "Removing Old BCP Stars Dekstop Shortcuts."
Remove-File -Path "$env:userprofile\Desktop\STARS PROD Portable" -Recurse
}
## Remove the previous BCP Stars Install ##
$OldStars = Test-Path "C:\Program Files (x86)\STARS\"
If ($OldStars -eq "True")
{
Write-Log "A version of BPC Stars is already installed, removing it and replacing it with the latest."
Remove-File -Path "C:\Program Files (x86)\STARS\" -Recurse
}
##*===============================================
##* INSTALLATION
##*===============================================
[string]$installPhase = 'Installation'
## Handle Zero-Config MSI Installations
If ($useDefaultMsi)
{
[hashtable]$ExecuteDefaultMSISplat = @{ Action = 'Install'; Path = $defaultMsiFile }; If ($defaultMstFile) { $ExecuteDefaultMSISplat.Add('Transform', $defaultMstFile) }
Execute-MSI @ExecuteDefaultMSISplat; If ($defaultMspFiles) { $defaultMspFiles | ForEach-Object { Execute-MSI -Action 'Patch' -Path $_ } }
}
## <Perform Installation tasks here>
New-Folder -Path "C:\Program Files (x86)\STARS\FireFoxPortable"
Copy-Item -Path "$dirFiles\FireFox Portable 75\*" -Destination "C:\Program Files (x86)\STARS\FireFoxPortable" -Recurse
## Copy the Icons to the Public Desktop ##
Write-Log "Copy the new shortcuts to the Public Desktop"
Copy-Item -Path "C:\Program Files (x86)\STARS\FireFoxPortable\*.lnk" -Destination "C:\Users\Public\Desktop"
Refresh-Desktop
##*===============================================
##* POST-INSTALLATION
##*===============================================
[string]$installPhase = 'Post-Installation'
## <Perform Post-Installation tasks here>
<# Legacy Block, unnecessary complication.
## Create a custom registry entry so that the application can be detected from SCCM ##
$HKLMCustomApp = "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\BPC STARS"
New-Item -Path $HKLMCustomApp
Set-ItemProperty -Path $HKLMCustomApp -Name DisplayName "BPC STARS (Only Uninstall from Software Center)"
Set-ItemProperty -Path $HKLMCustomApp -Name DisplayIcon "C:\Program Files (x86)\STARS\FireFoxPortable 75\firefox_0000.ico"
Set-ItemProperty -Path $HKLMCustomApp -Name UninstallString "C:\Program Files (x86\STARS\FireFoxPortable 75\firefoxportable.exe"
Set-ItemProperty -Path $HKLMCustomApp -Name DisplayVersion "75.0"
Set-ItemProperty -Path $HKLMCustomApp -Name Publisher "NCHRI Biopathology Center"
$Name = "NoModify"
$value = "1"
IF (!(Test-Path $HKLMCustomApp))
{
New-Item -Path $HKLMCustomApp -Force | Out-Null
New-ItemProperty -Path $HKLMCustomApp -Name $name -Value $value -PropertyType DWORD -Force | Out-Null
}
ELSE
{
New-ItemProperty -Path $HKLMCustomApp -Name $name -Value $value -PropertyType DWORD -Force | Out-Null
}
#>
## Set the Permissions on the Firefox Portable folder. ##
CACLS "C:\Program Files (x86)\STARS\FireFoxPortable" /e /t /p Users:f
## Display a message at the end of the install
If (-not $useDefaultMsi)
{
#Show-InstallationPrompt -Message 'You can customize text to appear at the end of an install or remove it completely for unattended installations.' -ButtonRightText 'OK' -Icon Information -NoWait }
}
}
ElseIf ($deploymentType -ieq 'Uninstall')
{
##*===============================================
##* PRE-UNINSTALLATION
##*===============================================
[string]$installPhase = 'Pre-Uninstallation'
## Show Welcome Message, close Internet Explorer with a 60 second countdown before automatically closing
Show-InstallationWelcome -CloseApps 'FirefoxPortable' -CloseAppsCountdown 60
## Show Progress Message (with the default message)
Show-InstallationProgress
## <Perform Pre-Uninstallation tasks here>
##*===============================================
##* UNINSTALLATION
##*===============================================
[string]$installPhase = 'Uninstallation'
## Handle Zero-Config MSI Uninstallations
If ($useDefaultMsi)
{
[hashtable]$ExecuteDefaultMSISplat = @{ Action = 'Uninstall'; Path = $defaultMsiFile }; If ($defaultMstFile) { $ExecuteDefaultMSISplat.Add('Transform', $defaultMstFile) }
Execute-MSI @ExecuteDefaultMSISplat
}
# <Perform Uninstallation tasks here>
## Removes FireFox Portable ##
Remove-File -Path "C:\Program Files (x86)\STARS\" -Recurse
##*===============================================
##* POST-UNINSTALLATION
##*===============================================
[string]$installPhase = 'Post-Uninstallation'
## <Perform Post-Uninstallation tasks here>
# Remove the Shortcuts ##
## Remove any of the old BPC Stars Shortcuts from the Public Desktop ##
$ProdLnk = Test-Path "C:\Users\Public\Desktop\STARS PROD.lnk"
$Traning = Test-Path "C:\Users\Public\Desktop\STARS Training.lnk"
If ($ProdLnk -eq "True")
{
Remove-Item -Path "C:\Users\Public\Desktop\STARS PROD.lnk" -Recurse
}
If ($Training -eq "True")
{
Remove-Item -Path "C:\Users\Public\Desktop\STARS Training.lnk" -Recurse
}
## Remove any of the old BPC Stars Shortcuts from the Users Desktop ##
$ProdLnkUser = Test-Path "$env:userprofile\Desktop\STARS PROD.lnk"
$TraningUser = Test-Path "$env:userprofile\Desktop\STARS Training.lnk"
If ($ProdLnkUser -eq "True")
{
Remove-File -Path "$env:userprofile\Desktop\STARS PROD.lnk" -Recurse
}
If ($TrainingUser -eq "True")
{
Remove-File -Path "$env:userprofile\Desktop\STARS Training.lnk" -Recurse
}
}
ElseIf ($deploymentType -ieq 'Repair')
{
##*===============================================
##* PRE-REPAIR
##*===============================================
[string]$installPhase = 'Pre-Repair'
## Show Progress Message (with the default message)
Show-InstallationProgress
## <Perform Pre-Repair tasks here>
##*===============================================
##* REPAIR
##*===============================================
[string]$installPhase = 'Repair'
## Handle Zero-Config MSI Repairs
If ($useDefaultMsi)
{
[hashtable]$ExecuteDefaultMSISplat = @{ Action = 'Repair'; Path = $defaultMsiFile; }; If ($defaultMstFile) { $ExecuteDefaultMSISplat.Add('Transform', $defaultMstFile) }
Execute-MSI @ExecuteDefaultMSISplat
}
# <Perform Repair tasks here>
##*===============================================
##* POST-REPAIR
##*===============================================
[string]$installPhase = 'Post-Repair'
## <Perform Post-Repair tasks here>
}
##*===============================================
##* END SCRIPT BODY
##*===============================================
## Call the Exit-Script function to perform final cleanup operations
Exit-Script -ExitCode $mainExitCode
}
Catch
{
[int32]$mainExitCode = 60001
[string]$mainErrorMessage = "$(Resolve-Error)"
Write-Log -Message $mainErrorMessage -Severity 3 -Source $deployAppScriptFriendlyName
Show-DialogBox -Text $mainErrorMessage -Icon 'Stop'
Exit-Script -ExitCode $mainExitCode
}

View File

@@ -0,0 +1,475 @@
<#
.SYNOPSIS
This script performs the installation or uninstallation of an application(s).
# LICENSE #
PowerShell App Deployment Toolkit - Provides a set of functions to perform common application deployment tasks on Windows.
Copyright (C) 2017 - Sean Lillis, Dan Cunningham, Muhammad Mashwani, Aman Motazedian.
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
.DESCRIPTION
The script is provided as a template to perform an install or uninstall of an application(s).
The script either performs an "Install" deployment type or an "Uninstall" deployment type.
The install deployment type is broken down into 3 main sections/phases: Pre-Install, Install, and Post-Install.
The script dot-sources the AppDeployToolkitMain.ps1 script which contains the logic and functions required to install or uninstall an application.
.PARAMETER DeploymentType
The type of deployment to perform. Default is: Install.
.PARAMETER DeployMode
Specifies whether the installation should be run in Interactive, Silent, or NonInteractive mode. Default is: Interactive. Options: Interactive = Shows dialogs, Silent = No dialogs, NonInteractive = Very silent, i.e. no blocking apps. NonInteractive mode is automatically set if it is detected that the process is not user interactive.
.PARAMETER AllowRebootPassThru
Allows the 3010 return code (requires restart) to be passed back to the parent process (e.g. SCCM) if detected from an installation. If 3010 is passed back to SCCM, a reboot prompt will be triggered.
.PARAMETER TerminalServerMode
Changes to "user install mode" and back to "user execute mode" for installing/uninstalling applications for Remote Destkop Session Hosts/Citrix servers.
.PARAMETER DisableLogging
Disables logging to file for the script. Default is: $false.
.EXAMPLE
powershell.exe -Command "& { & '.\Deploy-Application.ps1' -DeployMode 'Silent'; Exit $LastExitCode }"
.EXAMPLE
powershell.exe -Command "& { & '.\Deploy-Application.ps1' -AllowRebootPassThru; Exit $LastExitCode }"
.EXAMPLE
powershell.exe -Command "& { & '.\Deploy-Application.ps1' -DeploymentType 'Uninstall'; Exit $LastExitCode }"
.EXAMPLE
Deploy-Application.exe -DeploymentType "Install" -DeployMode "Silent"
.NOTES
Toolkit Exit Code Ranges:
60000 - 68999: Reserved for built-in exit codes in Deploy-Application.ps1, Deploy-Application.exe, and AppDeployToolkitMain.ps1
69000 - 69999: Recommended for user customized exit codes in Deploy-Application.ps1
70000 - 79999: Recommended for user customized exit codes in AppDeployToolkitExtensions.ps1
.LINK
http://psappdeploytoolkit.com
#>
[CmdletBinding()]
Param (
[Parameter(Mandatory = $false)]
[ValidateSet('Install', 'Uninstall', 'Repair')]
[string]$DeploymentType = 'Install',
[Parameter(Mandatory = $false)]
[ValidateSet('Interactive', 'Silent', 'NonInteractive')]
[string]$DeployMode = 'Interactive',
[Parameter(Mandatory = $false)]
[switch]$AllowRebootPassThru = $false,
[Parameter(Mandatory = $false)]
[switch]$TerminalServerMode = $false,
[Parameter(Mandatory = $false)]
[switch]$DisableLogging = $false
)
Try
{
## Set the script execution policy for this process
Try { Set-ExecutionPolicy -ExecutionPolicy 'ByPass' -Scope 'Process' -Force -ErrorAction 'Stop' }
Catch { }
##*===============================================
##* VARIABLE DECLARATION
##*===============================================
## Variables: Application
[string]$appVendor = 'NCHRI BioPathology Center'
[string]$appName = 'BPC Stars'
[string]$appVersion = ''
[string]$appArch = ''
[string]$appLang = 'EN'
[string]$appRevision = '01'
[string]$appScriptVersion = '1.0.0'
[string]$appScriptDate = '04/02/2021'
[string]$appScriptAuthor = 'John Palmer'
##*===============================================
## Variables: Install Titles (Only set here to override defaults set by the toolkit)
[string]$installName = ''
[string]$installTitle = ''
##* Do not modify section below
#region DoNotModify
## Variables: Exit Code
[int32]$mainExitCode = 0
## Variables: Script
[string]$deployAppScriptFriendlyName = 'Deploy Application'
[version]$deployAppScriptVersion = [version]'3.8.3'
[string]$deployAppScriptDate = '30/09/2020'
[hashtable]$deployAppScriptParameters = $psBoundParameters
## Variables: Environment
If (Test-Path -LiteralPath 'variable:HostInvocation') { $InvocationInfo = $HostInvocation }
Else { $InvocationInfo = $MyInvocation }
[string]$scriptDirectory = Split-Path -Path $InvocationInfo.MyCommand.Definition -Parent
## Dot source the required App Deploy Toolkit Functions
Try
{
[string]$moduleAppDeployToolkitMain = "$scriptDirectory\AppDeployToolkit\AppDeployToolkitMain.ps1"
If (-not (Test-Path -LiteralPath $moduleAppDeployToolkitMain -PathType 'Leaf')) { Throw "Module does not exist at the specified location [$moduleAppDeployToolkitMain]." }
If ($DisableLogging) { . $moduleAppDeployToolkitMain -DisableLogging }
Else { . $moduleAppDeployToolkitMain }
}
Catch
{
If ($mainExitCode -eq 0) { [int32]$mainExitCode = 60008 }
Write-Error -Message "Module [$moduleAppDeployToolkitMain] failed to load: `n$($_.Exception.Message)`n `n$($_.InvocationInfo.PositionMessage)" -ErrorAction 'Continue'
## Exit the script, returning the exit code to SCCM
If (Test-Path -LiteralPath 'variable:HostInvocation') { $script:ExitCode = $mainExitCode; Exit }
Else { Exit $mainExitCode }
}
#endregion
##* Do not modify section above
##*===============================================
##* END VARIABLE DECLARATION
##*===============================================
If ($deploymentType -ine 'Uninstall' -and $deploymentType -ine 'Repair')
{
##*===============================================
##* PRE-INSTALLATION
##*===============================================
[string]$installPhase = 'Pre-Installation'
## Show Welcome Message, close Internet Explorer if required, allow up to 3 deferrals, verify there is enough disk space to complete the install, and persist the prompt
#Show-InstallationWelcome -CloseApps 'iexplore' -AllowDefer -DeferTimes 3 -CheckDiskSpace -PersistPrompt
$ProcessActive = Get-Process FirefoxPOrtable -ErrorAction SilentlyContinue
if ($ProcessActive -eq $null)
{
Write-Log "BPC Stars is not currently running, continuing with the installation."
}
else
{
Write-Log "BPC Stars is currently running, prompting the user to close the application before continuing."
Show-InstallationWelcome -CloseApps 'FirefoxPOrtable,firefox' -AllowDefer -DeferTimes 3 -CheckDiskSpace -PersistPrompt
}
## Show Progress Message (with the default message)
#Show-InstallationProgress
## <Perform Pre-Installation tasks here>
## Remove any of the old BPC Stars Shortcuts from the Public Desktop ##
$OldProdLnk = Test-Path "C:\Users\Public\Desktop\STARS PROD.lnk"
$OldUAT2lnk = Test-Path "C:\Users\Public\Desktop\STARS UAT2.lnk"
$OldUAT1lnk = Test-Path "C:\Users\Public\Desktop\STARS UAT1.lnk"
$OldBreaKFix = Test-Path "C:\Users\Public\Desktop\Breakfix.lnk"
$OldTraining = Test-Path "C:\Users\Public\Desktop\STARS_Training Portable.lnk"
$OldProdPort = Test-Path "C:\Users\Public\Desktop\STARS PROD Portable.lnk"
If ($OldProdLnk -eq "True")
{
Write-Log "Removing Stars Prod Public Desktop Shortcut."
Remove-File -Path "C:\Users\Public\Desktop\STARS PROD.lnk" -Recurse
}
If ($OldUAT2lnk -eq "True")
{
Write-Log "Removing Stars UAT2 Public Desktop Shortcut."
Remove-File -Path "C:\Users\Public\Desktop\STARS UAT2.lnk" -Recurse
}
If ($OldUAT1lnk -eq "True")
{
Write-Log "Removing Stars UAT1 Public Desktop Shortcut."
Remove-File -Path "C:\Users\Public\Desktop\STARS UAT1.lnk" -Recurse
}
If ($OldBreaKFix -eq "True")
{
Write-Log "Removing Stars UAT1 Public Desktop Shortcut."
Remove-File -Path "C:\Users\Public\Desktop\STARS UAT1.lnk" -Recurse
}
If ($OldTraining -eq "True")
{
Write-Log "Removing Stars UAT1 Public Desktop Shortcut."
Remove-File -Path "C:\Users\Public\Desktop\STARS_Training Portable.lnk" -Recurse
}
if ($OldProdPort -eq "True")
{
Write-Log "Removing Stars UAT1 Public Desktop Shortcut."
Remove-File -Path "C:\Users\Public\Desktop\STARS PROD Portable.lnk" -Recurse
}
## Remove any of the old BPC Stars Shortcuts from the Users Desktop ##
$OldProdLnkUser = Test-Path "$env:userprofile\Desktop\STARS PROD.lnk"
$OldUAT2lnkUser = Test-Path "$env:userprofile\Desktop\STARS UAT2.lnk"
$OldUAT1lnkUser = Test-Path "$env:userprofile\Desktop\STARS UAT1.lnk"
$OldBreaKFixUser = Test-Path "$env:userprofile\Desktop\Breakfix.lnk"
$OldTrainingUser = Test-Path "$env:userprofile\Desktop\STARS_Training Portable.lnk"
$OldProdPort = Test-Path "$env:USERPROFILE\Desktop\STARS PROD Portable.lnk"
If ($OldProdLnkUser -eq "True")
{
Write-Log "Removing Old BCP Stars Dekstop Shortcuts."
Remove-File -Path "$env:userprofile\Desktop\STARS PROD.lnk" -Recurse
}
If ($OldUAT2lnkUser -eq "True")
{
Write-Log "Removing Old BCP Stars Dekstop Shortcuts."
Remove-File -Path "$env:userprofile\Desktop\STARS UAT2.lnk" -Recurse
}
If ($OldUAT1lnkUser -eq "True")
{
Write-Log "Removing Old BCP Stars Dekstop Shortcuts."
Remove-File -Path "$env:userprofile\Desktop\STARS UAT1.lnk" -Recurse
}
If ($OldBreaKFixUser -eq "True")
{
Write-Log "Removing Old BCP Stars Dekstop Shortcuts."
Remove-File -Path "$env:userprofile\Desktop\STARS UAT1.lnk" -Recurse
}
If ($OldTrainingUser -eq "True")
{
Write-Log "Removing Old BCP Stars Dekstop Shortcuts."
Remove-File -Path "$env:userprofile\Desktop\STARS_Training Portable.lnk" -Recurse
}
If ($OldProdPort -eq "True")
{
Write-Log "Removing Old BCP Stars Dekstop Shortcuts."
Remove-File -Path "$env:userprofile\Desktop\STARS PROD Portable" -Recurse
}
## Remove the previous BCP Stars Install ##
$OldStars = Test-Path "C:\Program Files (x86)\STARS\"
If ($OldStars -eq "True")
{
Write-Log "A version of BPC Stars is already installed, removing it and replacing it with the latest."
Remove-File -Path "C:\Program Files (x86)\STARS\" -Recurse
}
##*===============================================
##* INSTALLATION
##*===============================================
[string]$installPhase = 'Installation'
## Handle Zero-Config MSI Installations
If ($useDefaultMsi)
{
[hashtable]$ExecuteDefaultMSISplat = @{ Action = 'Install'; Path = $defaultMsiFile }; If ($defaultMstFile) { $ExecuteDefaultMSISplat.Add('Transform', $defaultMstFile) }
Execute-MSI @ExecuteDefaultMSISplat; If ($defaultMspFiles) { $defaultMspFiles | ForEach-Object { Execute-MSI -Action 'Patch' -Path $_ } }
}
## <Perform Installation tasks here>
New-Folder -Path "C:\Program Files (x86)\STARS\FireFoxPortable"
Copy-Item -Path "$dirFiles\FireFox Portable 75\*" -Destination "C:\Program Files (x86)\STARS\FireFoxPortable" -Recurse
## Copy the Icons to the Public Desktop ##
Write-Log "Copy the new shortcuts to the Public Desktop"
Copy-Item -Path "C:\Program Files (x86)\STARS\FireFoxPortable\*.lnk" -Destination "C:\Users\Public\Desktop"
Refresh-Desktop
##*===============================================
##* POST-INSTALLATION
##*===============================================
[string]$installPhase = 'Post-Installation'
## <Perform Post-Installation tasks here>
<# Legacy Block, unnecessary complication.
## Create a custom registry entry so that the application can be detected from SCCM ##
$HKLMCustomApp = "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\BPC STARS"
New-Item -Path $HKLMCustomApp
Set-ItemProperty -Path $HKLMCustomApp -Name DisplayName "BPC STARS (Only Uninstall from Software Center)"
Set-ItemProperty -Path $HKLMCustomApp -Name DisplayIcon "C:\Program Files (x86)\STARS\FireFoxPortable 75\firefox_0000.ico"
Set-ItemProperty -Path $HKLMCustomApp -Name UninstallString "C:\Program Files (x86\STARS\FireFoxPortable 75\firefoxportable.exe"
Set-ItemProperty -Path $HKLMCustomApp -Name DisplayVersion "75.0"
Set-ItemProperty -Path $HKLMCustomApp -Name Publisher "NCHRI Biopathology Center"
$Name = "NoModify"
$value = "1"
IF (!(Test-Path $HKLMCustomApp))
{
New-Item -Path $HKLMCustomApp -Force | Out-Null
New-ItemProperty -Path $HKLMCustomApp -Name $name -Value $value -PropertyType DWORD -Force | Out-Null
}
ELSE
{
New-ItemProperty -Path $HKLMCustomApp -Name $name -Value $value -PropertyType DWORD -Force | Out-Null
}
#>
## Set the Permissions on the Firefox Portable folder. ##
CACLS "C:\Program Files (x86)\STARS\FireFoxPortable" /e /t /p Users:f
## Display a message at the end of the install
If (-not $useDefaultMsi)
{
#Show-InstallationPrompt -Message 'You can customize text to appear at the end of an install or remove it completely for unattended installations.' -ButtonRightText 'OK' -Icon Information -NoWait }
}
}
ElseIf ($deploymentType -ieq 'Uninstall')
{
##*===============================================
##* PRE-UNINSTALLATION
##*===============================================
[string]$installPhase = 'Pre-Uninstallation'
## Show Welcome Message, close Internet Explorer with a 60 second countdown before automatically closing
Show-InstallationWelcome -CloseApps 'FirefoxPortable' -CloseAppsCountdown 60
## Show Progress Message (with the default message)
Show-InstallationProgress
## <Perform Pre-Uninstallation tasks here>
##*===============================================
##* UNINSTALLATION
##*===============================================
[string]$installPhase = 'Uninstallation'
## Handle Zero-Config MSI Uninstallations
If ($useDefaultMsi)
{
[hashtable]$ExecuteDefaultMSISplat = @{ Action = 'Uninstall'; Path = $defaultMsiFile }; If ($defaultMstFile) { $ExecuteDefaultMSISplat.Add('Transform', $defaultMstFile) }
Execute-MSI @ExecuteDefaultMSISplat
}
# <Perform Uninstallation tasks here>
## Removes FireFox Portable ##
Remove-File -Path "C:\Program Files (x86)\STARS\" -Recurse
##*===============================================
##* POST-UNINSTALLATION
##*===============================================
[string]$installPhase = 'Post-Uninstallation'
## <Perform Post-Uninstallation tasks here>
# Remove the Shortcuts ##
## Remove any of the old BPC Stars Shortcuts from the Public Desktop ##
$ProdLnk = Test-Path "C:\Users\Public\Desktop\STARS PROD.lnk"
$Traning = Test-Path "C:\Users\Public\Desktop\STARS Training.lnk"
If ($ProdLnk -eq "True")
{
Remove-Item -Path "C:\Users\Public\Desktop\STARS PROD.lnk" -Recurse
}
If ($Training -eq "True")
{
Remove-Item -Path "C:\Users\Public\Desktop\STARS Training.lnk" -Recurse
}
## Remove any of the old BPC Stars Shortcuts from the Users Desktop ##
$ProdLnkUser = Test-Path "$env:userprofile\Desktop\STARS PROD.lnk"
$TraningUser = Test-Path "$env:userprofile\Desktop\STARS Training.lnk"
If ($ProdLnkUser -eq "True")
{
Remove-File -Path "$env:userprofile\Desktop\STARS PROD.lnk" -Recurse
}
If ($TrainingUser -eq "True")
{
Remove-File -Path "$env:userprofile\Desktop\STARS Training.lnk" -Recurse
}
}
ElseIf ($deploymentType -ieq 'Repair')
{
##*===============================================
##* PRE-REPAIR
##*===============================================
[string]$installPhase = 'Pre-Repair'
## Show Progress Message (with the default message)
Show-InstallationProgress
## <Perform Pre-Repair tasks here>
##*===============================================
##* REPAIR
##*===============================================
[string]$installPhase = 'Repair'
## Handle Zero-Config MSI Repairs
If ($useDefaultMsi)
{
[hashtable]$ExecuteDefaultMSISplat = @{ Action = 'Repair'; Path = $defaultMsiFile; }; If ($defaultMstFile) { $ExecuteDefaultMSISplat.Add('Transform', $defaultMstFile) }
Execute-MSI @ExecuteDefaultMSISplat
}
# <Perform Repair tasks here>
##*===============================================
##* POST-REPAIR
##*===============================================
[string]$installPhase = 'Post-Repair'
## <Perform Post-Repair tasks here>
}
##*===============================================
##* END SCRIPT BODY
##*===============================================
## Call the Exit-Script function to perform final cleanup operations
Exit-Script -ExitCode $mainExitCode
}
Catch
{
[int32]$mainExitCode = 60001
[string]$mainErrorMessage = "$(Resolve-Error)"
Write-Log -Message $mainErrorMessage -Severity 3 -Source $deployAppScriptFriendlyName
Show-DialogBox -Text $mainErrorMessage -Icon 'Stop'
Exit-Script -ExitCode $mainExitCode
}

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0"/>
<supportedRuntime version="v2.0.50727"/>
</startup>
</configuration>

View File

@@ -0,0 +1,441 @@
<#
.SYNOPSIS
This script performs the installation or uninstallation of an application(s).
# LICENSE #
PowerShell App Deployment Toolkit - Provides a set of functions to perform common application deployment tasks on Windows.
Copyright (C) 2017 - Sean Lillis, Dan Cunningham, Muhammad Mashwani, Aman Motazedian.
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
.DESCRIPTION
The script is provided as a template to perform an install or uninstall of an application(s).
The script either performs an "Install" deployment type or an "Uninstall" deployment type.
The install deployment type is broken down into 3 main sections/phases: Pre-Install, Install, and Post-Install.
The script dot-sources the AppDeployToolkitMain.ps1 script which contains the logic and functions required to install or uninstall an application.
.PARAMETER DeploymentType
The type of deployment to perform. Default is: Install.
.PARAMETER DeployMode
Specifies whether the installation should be run in Interactive, Silent, or NonInteractive mode. Default is: Interactive. Options: Interactive = Shows dialogs, Silent = No dialogs, NonInteractive = Very silent, i.e. no blocking apps. NonInteractive mode is automatically set if it is detected that the process is not user interactive.
.PARAMETER AllowRebootPassThru
Allows the 3010 return code (requires restart) to be passed back to the parent process (e.g. SCCM) if detected from an installation. If 3010 is passed back to SCCM, a reboot prompt will be triggered.
.PARAMETER TerminalServerMode
Changes to "user install mode" and back to "user execute mode" for installing/uninstalling applications for Remote Destkop Session Hosts/Citrix servers.
.PARAMETER DisableLogging
Disables logging to file for the script. Default is: $false.
.EXAMPLE
powershell.exe -Command "& { & '.\Deploy-Application.ps1' -DeployMode 'Silent'; Exit $LastExitCode }"
.EXAMPLE
powershell.exe -Command "& { & '.\Deploy-Application.ps1' -AllowRebootPassThru; Exit $LastExitCode }"
.EXAMPLE
powershell.exe -Command "& { & '.\Deploy-Application.ps1' -DeploymentType 'Uninstall'; Exit $LastExitCode }"
.EXAMPLE
Deploy-Application.exe -DeploymentType "Install" -DeployMode "Silent"
.NOTES
Toolkit Exit Code Ranges:
60000 - 68999: Reserved for built-in exit codes in Deploy-Application.ps1, Deploy-Application.exe, and AppDeployToolkitMain.ps1
69000 - 69999: Recommended for user customized exit codes in Deploy-Application.ps1
70000 - 79999: Recommended for user customized exit codes in AppDeployToolkitExtensions.ps1
.LINK
http://psappdeploytoolkit.com
#>
[CmdletBinding()]
Param (
[Parameter(Mandatory = $false)]
[ValidateSet('Install', 'Uninstall', 'Repair')]
[string]$DeploymentType = 'Install',
[Parameter(Mandatory = $false)]
[ValidateSet('Interactive', 'Silent', 'NonInteractive')]
[string]$DeployMode = 'Interactive',
[Parameter(Mandatory = $false)]
[switch]$AllowRebootPassThru = $false,
[Parameter(Mandatory = $false)]
[switch]$TerminalServerMode = $false,
[Parameter(Mandatory = $false)]
[switch]$DisableLogging = $false
)
Try
{
## Set the script execution policy for this process
Try { Set-ExecutionPolicy -ExecutionPolicy 'ByPass' -Scope 'Process' -Force -ErrorAction 'Stop' }
Catch { }
##*===============================================
##* VARIABLE DECLARATION
##*===============================================
## Variables: Application
[string]$appVendor = 'NCHRI BioPathology Center'
[string]$appName = 'BPC Stars'
[string]$appVersion = ''
[string]$appArch = ''
[string]$appLang = 'EN'
[string]$appRevision = '01'
[string]$appScriptVersion = '1.0.0'
[string]$appScriptDate = '04/02/2021'
[string]$appScriptAuthor = 'John Palmer'
##*===============================================
## Variables: Install Titles (Only set here to override defaults set by the toolkit)
[string]$installName = ''
[string]$installTitle = ''
##* Do not modify section below
#region DoNotModify
## Variables: Exit Code
[int32]$mainExitCode = 0
## Variables: Script
[string]$deployAppScriptFriendlyName = 'Deploy Application'
[version]$deployAppScriptVersion = [version]'3.8.3'
[string]$deployAppScriptDate = '30/09/2020'
[hashtable]$deployAppScriptParameters = $psBoundParameters
## Variables: Environment
If (Test-Path -LiteralPath 'variable:HostInvocation') { $InvocationInfo = $HostInvocation }
Else { $InvocationInfo = $MyInvocation }
[string]$scriptDirectory = Split-Path -Path $InvocationInfo.MyCommand.Definition -Parent
## Dot source the required App Deploy Toolkit Functions
Try
{
[string]$moduleAppDeployToolkitMain = "$scriptDirectory\AppDeployToolkit\AppDeployToolkitMain.ps1"
If (-not (Test-Path -LiteralPath $moduleAppDeployToolkitMain -PathType 'Leaf')) { Throw "Module does not exist at the specified location [$moduleAppDeployToolkitMain]." }
If ($DisableLogging) { . $moduleAppDeployToolkitMain -DisableLogging }
Else { . $moduleAppDeployToolkitMain }
}
Catch
{
If ($mainExitCode -eq 0) { [int32]$mainExitCode = 60008 }
Write-Error -Message "Module [$moduleAppDeployToolkitMain] failed to load: `n$($_.Exception.Message)`n `n$($_.InvocationInfo.PositionMessage)" -ErrorAction 'Continue'
## Exit the script, returning the exit code to SCCM
If (Test-Path -LiteralPath 'variable:HostInvocation') { $script:ExitCode = $mainExitCode; Exit }
Else { Exit $mainExitCode }
}
#endregion
##* Do not modify section above
##*===============================================
##* END VARIABLE DECLARATION
##*===============================================
If ($deploymentType -ine 'Uninstall' -and $deploymentType -ine 'Repair')
{
##*===============================================
##* PRE-INSTALLATION
##*===============================================
[string]$installPhase = 'Pre-Installation'
## Show Welcome Message, close Internet Explorer if required, allow up to 3 deferrals, verify there is enough disk space to complete the install, and persist the prompt
#Show-InstallationWelcome -CloseApps 'iexplore' -AllowDefer -DeferTimes 3 -CheckDiskSpace -PersistPrompt
$ProcessActive = Get-Process FirefoxPOrtable -ErrorAction SilentlyContinue
if ($ProcessActive -eq $null)
{
Write-Log "BPC Stars is not currently running, continuing with the installation."
}
else
{
Write-Log "BPC Stars is currently running, prompting the user to close the application before continuing."
Show-InstallationWelcome -CloseApps 'FirefoxPOrtable,firefox' -AllowDefer -DeferTimes 3 -CheckDiskSpace -PersistPrompt
}
## Show Progress Message (with the default message)
#Show-InstallationProgress
## <Perform Pre-Installation tasks here>
## Remove any of the old BPC Stars Shortcuts from the Public Desktop ##
$OldProdLnk = Test-Path "C:\Users\Public\Desktop\STARS PROD.lnk"
$OldUAT2lnk = Test-Path "C:\Users\Public\Desktop\STARS UAT2.lnk"
$OldUAT1lnk = Test-Path "C:\Users\Public\Desktop\STARS UAT1.lnk"
$OldBreaKFix = Test-Path "C:\Users\Public\Desktop\Breakfix.lnk"
$OldTraining = Test-Path "C:\Users\Public\Desktop\STARS_Training Portable.lnk"
$OldProdPort = Test-Path "C:\Users\Public\Desktop\STARS PROD Portable.lnk"
If ($OldProdLnk -eq "True")
{
Write-Log "Removing Stars Prod Public Desktop Shortcut."
Remove-File -Path "C:\Users\Public\Desktop\STARS PROD.lnk" -Recurse
}
If ($OldUAT2lnk -eq "True")
{
Write-Log "Removing Stars UAT2 Public Desktop Shortcut."
Remove-File -Path "C:\Users\Public\Desktop\STARS UAT2.lnk" -Recurse
}
If ($OldUAT1lnk -eq "True")
{
Write-Log "Removing Stars UAT1 Public Desktop Shortcut."
Remove-File -Path "C:\Users\Public\Desktop\STARS UAT1.lnk" -Recurse
}
If ($OldBreaKFix -eq "True")
{
Write-Log "Removing Stars UAT1 Public Desktop Shortcut."
Remove-File -Path "C:\Users\Public\Desktop\STARS UAT1.lnk" -Recurse
}
If ($OldTraining -eq "True")
{
Write-Log "Removing Stars UAT1 Public Desktop Shortcut."
Remove-File -Path "C:\Users\Public\Desktop\STARS_Training Portable.lnk" -Recurse
}
if ($OldProdPort -eq "True")
{
Write-Log "Removing Stars UAT1 Public Desktop Shortcut."
Remove-File -Path "C:\Users\Public\Desktop\STARS PROD Portable.lnk" -Recurse
}
## Remove any of the old BPC Stars Shortcuts from the Users Desktop ##
$Users = Get-ChildItem -Path "C:\Users"
foreach ($user in $Users)
{
Remove-Item -Path "C:\Users\$user\Desktop\STARS PROD.lnk" -Recurse
Remove-Item -Path "C:\Users\$user\Desktop\STARS UAT2.lnk" -Recurse
Remove-Item -Path "C:\Users\$user\Desktop\STARS UAT1.lnk" -Recurse
Remove-Item -Path "C:\Users\$user\Desktop\Breakfix.lnk" -Recurse
Remove-Item -Path "C:\Users\$user\Desktop\STARS_Training Portable.lnk" -Recurse
Remove-Item -Path "C:\Users\$user\Desktop\STARS PROD Portable.lnk" -Recurse
}
## Remove the previous BCP Stars Install ##
$OldStars = Test-Path "C:\Program Files (x86)\STARS\"
If ($OldStars -eq "True")
{
Write-Log "A version of BPC Stars is already installed, removing it and replacing it with the latest."
Remove-File -Path "C:\Program Files (x86)\STARS\" -Recurse
}
##*===============================================
##* INSTALLATION
##*===============================================
[string]$installPhase = 'Installation'
## Handle Zero-Config MSI Installations
If ($useDefaultMsi)
{
[hashtable]$ExecuteDefaultMSISplat = @{ Action = 'Install'; Path = $defaultMsiFile }; If ($defaultMstFile) { $ExecuteDefaultMSISplat.Add('Transform', $defaultMstFile) }
Execute-MSI @ExecuteDefaultMSISplat; If ($defaultMspFiles) { $defaultMspFiles | ForEach-Object { Execute-MSI -Action 'Patch' -Path $_ } }
}
## <Perform Installation tasks here>
New-Folder -Path "C:\Program Files (x86)\STARS\FireFoxPortable"
Copy-Item -Path "$dirFiles\FireFox Portable 75\*" -Destination "C:\Program Files (x86)\STARS\FireFoxPortable" -Recurse
## Copy the Icons to the Public Desktop ##
Write-Log "Copy the new shortcuts to the Public Desktop"
Copy-Item -Path "C:\Program Files (x86)\STARS\FireFoxPortable\*.lnk" -Destination "C:\Users\Public\Desktop"
Refresh-Desktop
##*===============================================
##* POST-INSTALLATION
##*===============================================
[string]$installPhase = 'Post-Installation'
## <Perform Post-Installation tasks here>
<# Legacy Block, unnecessary complication.
## Create a custom registry entry so that the application can be detected from SCCM ##
$HKLMCustomApp = "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\BPC STARS"
New-Item -Path $HKLMCustomApp
Set-ItemProperty -Path $HKLMCustomApp -Name DisplayName "BPC STARS (Only Uninstall from Software Center)"
Set-ItemProperty -Path $HKLMCustomApp -Name DisplayIcon "C:\Program Files (x86)\STARS\FireFoxPortable 75\firefox_0000.ico"
Set-ItemProperty -Path $HKLMCustomApp -Name UninstallString "C:\Program Files (x86\STARS\FireFoxPortable 75\firefoxportable.exe"
Set-ItemProperty -Path $HKLMCustomApp -Name DisplayVersion "75.0"
Set-ItemProperty -Path $HKLMCustomApp -Name Publisher "NCHRI Biopathology Center"
$Name = "NoModify"
$value = "1"
IF (!(Test-Path $HKLMCustomApp))
{
New-Item -Path $HKLMCustomApp -Force | Out-Null
New-ItemProperty -Path $HKLMCustomApp -Name $name -Value $value -PropertyType DWORD -Force | Out-Null
}
ELSE
{
New-ItemProperty -Path $HKLMCustomApp -Name $name -Value $value -PropertyType DWORD -Force | Out-Null
}
#>
## Set the Permissions on the Firefox Portable folder. ##
CACLS "C:\Program Files (x86)\STARS\FireFoxPortable" /e /t /p Users:f
## Display a message at the end of the install
If (-not $useDefaultMsi)
{
#Show-InstallationPrompt -Message 'You can customize text to appear at the end of an install or remove it completely for unattended installations.' -ButtonRightText 'OK' -Icon Information -NoWait }
}
}
ElseIf ($deploymentType -ieq 'Uninstall')
{
##*===============================================
##* PRE-UNINSTALLATION
##*===============================================
[string]$installPhase = 'Pre-Uninstallation'
## Show Welcome Message, close Internet Explorer with a 60 second countdown before automatically closing
Show-InstallationWelcome -CloseApps 'FirefoxPortable' -CloseAppsCountdown 60
## Show Progress Message (with the default message)
Show-InstallationProgress
## <Perform Pre-Uninstallation tasks here>
##*===============================================
##* UNINSTALLATION
##*===============================================
[string]$installPhase = 'Uninstallation'
## Handle Zero-Config MSI Uninstallations
If ($useDefaultMsi)
{
[hashtable]$ExecuteDefaultMSISplat = @{ Action = 'Uninstall'; Path = $defaultMsiFile }; If ($defaultMstFile) { $ExecuteDefaultMSISplat.Add('Transform', $defaultMstFile) }
Execute-MSI @ExecuteDefaultMSISplat
}
# <Perform Uninstallation tasks here>
## Removes FireFox Portable ##
Remove-File -Path "C:\Program Files (x86)\STARS\" -Recurse
##*===============================================
##* POST-UNINSTALLATION
##*===============================================
[string]$installPhase = 'Post-Uninstallation'
## <Perform Post-Uninstallation tasks here>
# Remove the Shortcuts ##
## Remove any of the old BPC Stars Shortcuts from the Public Desktop ##
$ProdLnk = Test-Path "C:\Users\Public\Desktop\STARS PROD.lnk"
$Training = Test-Path "C:\Users\Public\Desktop\STARS Training.lnk"
If ($ProdLnk -eq "True")
{
Remove-Item -Path "C:\Users\Public\Desktop\STARS PROD.lnk" -Recurse
}
If ($Training -eq "True")
{
Remove-Item -Path "C:\Users\Public\Desktop\STARS Training.lnk" -Recurse
}
## Remove any of the old BPC Stars Shortcuts from the Users Desktop ##
$ProdLnkUser = Test-Path "$env:userprofile\Desktop\STARS PROD.lnk"
$TraningUser = Test-Path "$env:userprofile\Desktop\STARS Training.lnk"
If ($ProdLnkUser -eq "True")
{
Remove-File -Path "$env:userprofile\Desktop\STARS PROD.lnk" -Recurse
}
If ($TrainingUser -eq "True")
{
Remove-File -Path "$env:userprofile\Desktop\STARS Training.lnk" -Recurse
}
}
ElseIf ($deploymentType -ieq 'Repair')
{
##*===============================================
##* PRE-REPAIR
##*===============================================
[string]$installPhase = 'Pre-Repair'
## Show Progress Message (with the default message)
Show-InstallationProgress
## <Perform Pre-Repair tasks here>
##*===============================================
##* REPAIR
##*===============================================
[string]$installPhase = 'Repair'
## Handle Zero-Config MSI Repairs
If ($useDefaultMsi)
{
[hashtable]$ExecuteDefaultMSISplat = @{ Action = 'Repair'; Path = $defaultMsiFile; }; If ($defaultMstFile) { $ExecuteDefaultMSISplat.Add('Transform', $defaultMstFile) }
Execute-MSI @ExecuteDefaultMSISplat
}
# <Perform Repair tasks here>
##*===============================================
##* POST-REPAIR
##*===============================================
[string]$installPhase = 'Post-Repair'
## <Perform Post-Repair tasks here>
}
##*===============================================
##* END SCRIPT BODY
##*===============================================
## Call the Exit-Script function to perform final cleanup operations
Exit-Script -ExitCode $mainExitCode
}
Catch
{
[int32]$mainExitCode = 60001
[string]$mainErrorMessage = "$(Resolve-Error)"
Write-Log -Message $mainErrorMessage -Severity 3 -Source $deployAppScriptFriendlyName
Show-DialogBox -Text $mainErrorMessage -Icon 'Stop'
Exit-Script -ExitCode $mainExitCode
}