PSSysTray.psm1
#region Private Functions #endregion #region Public Functions #region New-PSSysTrayConfigFile.ps1 ############################################ # source: New-PSSysTrayConfigFile.ps1 # Module: PSSysTray # version: 0.1.10 # Author: Pierre Smit # Company: HTPCZA Tech ############################################# <# .SYNOPSIS Creates the needed .csv file in the specified folder. .DESCRIPTION Creates the needed .csv file in the specified folder. .PARAMETER ConfigPath Path to where the config file will be saved. .PARAMETER CreateShortcut Create a shortcut to a .ps1 file that will launch the gui. .EXAMPLE New-PSSysTrayConfigFile -ConfigPath C:\temp -CreateShortcut #> Function New-PSSysTrayConfigFile { [Cmdletbinding(SupportsShouldProcess = $true, HelpURI = 'https://smitpi.github.io/PSSysTray/New-PSSysTrayConfigFile')] PARAM( [ValidateScript( { (Test-Path $_) })] [System.IO.DirectoryInfo]$ConfigPath, [switch]$CreateShortcut = $false ) [System.Collections.ArrayList]$Export = @() $export += [PSCustomObject]@{ MainMenu = 'Level1' ScriptName = 'TempScript' ScriptPath = 'C:\temp\script.ps1' Mode = 'PSFile' } $export += [PSCustomObject]@{ MainMenu = 'Level2' ScriptName = 'Command' ScriptPath = 'get-command' Mode = 'PSCommand' } $export += [PSCustomObject]@{ MainMenu = 'Level3' ScriptName = 'Restart' ScriptPath = 'shutdown /f /r /t 0' Mode = 'Other' } if ($pscmdlet.ShouldProcess('Target', 'Operation')) { $Configfile = (Join-Path $ConfigPath -ChildPath \PSSysTrayConfig.csv) $check = Test-Path -Path $Configfile -ErrorAction SilentlyContinue if (-not($check)) { Write-Output 'Config File does not exit, creating default settings.' $export | Export-Csv -Path $Configfile -NoClobber -NoTypeInformation } else { Write-Warning 'File exists, renaming file now' Rename-Item $Configfile -NewName "PSSysTrayConfig_$(Get-Date -Format ddMMyyyy_HHmm).csv" $export | Export-Csv -Path $Configfile -NoClobber -NoTypeInformation } if ($CreateShortcut) { $module = Get-Module PSSysTray if (![bool]$module) { $module = Get-Module PSSysTray -ListAvailable } $string = @" `$PRModule = Get-ChildItem `"$((Join-Path ((Get-Item $module.ModuleBase).Parent).FullName "\*\$($module.name).psm1"))`" | Sort-Object -Property LastWriteTime -Descending | Select-Object -First 1 import-module `$PRModule.fullname -Force Start-PSSysTray -ConfigFilePath $((Join-Path $ConfigPath -ChildPath \PSSysTrayConfig.csv -Resolve)) "@ Set-Content -Value $string -Path (Join-Path $ConfigPath -ChildPath \PSSysTray.ps1) | Get-Item $PSSysTray = (Join-Path $ConfigPath -ChildPath \PSSysTray.ps1) | Get-Item $WScriptShell = New-Object -ComObject WScript.Shell $lnkfile = ($PSSysTray.FullName).Replace('ps1', 'lnk') $Shortcut = $WScriptShell.CreateShortcut($($lnkfile)) $Shortcut.TargetPath = 'powershell.exe' $Shortcut.Arguments = "-NoLogo -NoProfile -WindowStyle Hidden -ExecutionPolicy bypass -file `"$($PSSysTray.FullName)`"" $icon = Get-Item (Join-Path $module.ModuleBase .\Private\PSSysTray.ico) $Shortcut.IconLocation = $icon.FullName $Shortcut.Save() Start-Process explorer.exe $ConfigPath } } } #end Function Export-ModuleMember -Function New-PSSysTrayConfigFile #endregion #region Start-PSSysTray.ps1 ############################################ # source: Start-PSSysTray.ps1 # Module: PSSysTray # version: 0.1.10 # Author: Pierre Smit # Company: HTPCZA Tech ############################################# <# .SYNOPSIS This function reads csv config file and creates the gui in your system tray. .DESCRIPTION This function reads csv config file and creates the gui in your system tray. .PARAMETER ConfigFilePath Path to the config file created by New-PSSysTrayConfigFile .EXAMPLE Start-PSSysTray -ConfigFilePath C:\temp\PSSysTrayConfig.csv #> Function Start-PSSysTray { [Cmdletbinding(SupportsShouldProcess = $true, HelpURI = "https://smitpi.github.io/PSSysTray/Start-PSSysTray")] Param ( [Parameter(Mandatory = $true, Position = 0)] [ValidateScript( { (Test-Path $_) -and ((Get-Item $_).Extension -eq '.csv') })] [string]$ConfigFilePath ) if ($pscmdlet.ShouldProcess('Target', 'Operation')) { Add-Type -Name Window -Namespace Console -MemberDefinition ' [DllImport("Kernel32.dll")] public static extern IntPtr GetConsoleWindow(); [DllImport("user32.dll")] public static extern bool ShowWindow(IntPtr hWnd, Int32 nCmdShow); ' # Declare assemblies [System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms') | Out-Null [System.Reflection.Assembly]::LoadWithPartialName('presentationframework') | Out-Null [System.Reflection.Assembly]::LoadWithPartialName('System.Drawing') | Out-Null [System.Reflection.Assembly]::LoadWithPartialName('WindowsFormsIntegration') | Out-Null # Add an icon to the systray button $module = Get-Module PSSysTray if (![bool]$module) { $module = Get-Module PSSysTray -ListAvailable } $icopath = (Join-Path $module.ModuleBase '\Private\PSSysTray.ico') | Get-Item $icon = [System.Drawing.Icon]::ExtractAssociatedIcon($icopath.FullName) # Create object for the systray $Systray_Tool_Icon = New-Object System.Windows.Forms.NotifyIcon # Text displayed when you pass the mouse over the systray icon $Systray_Tool_Icon.Text = 'PSSysTray Utils' # Systray icon $Systray_Tool_Icon.Icon = $icon $Systray_Tool_Icon.Visible = $true $contextmenu = New-Object System.Windows.Forms.ContextMenu $Systray_Tool_Icon.ContextMenu = $contextmenu function ShowConsole { $PSConsole = [Console.Window]::GetConsoleWindow() [Console.Window]::ShowWindow($PSConsole, 5) } function HideConsole { $PSConsole = [Console.Window]::GetConsoleWindow() [Console.Window]::ShowWindow($PSConsole, 0) } function NMenuItem { param( [string]$Text = 'Placeholder Text', $MyScriptPath, [ValidateSet('PSFile', 'PSCommand', 'Other')] [string]$method, [System.Windows.Forms.MenuItem]$MainMenu ) #Initialization $MenuItem = New-Object System.Windows.Forms.MenuItem #Apply desired text if ($Text) { $MenuItem.Text = $Text } #Apply click event logic if ($MyScriptPath -and !$ExitOnly) { $MenuItem | Add-Member -Name MyScriptPath -Value $MyScriptPath -MemberType NoteProperty if ($method -eq 'PSFile') { $MenuItem.Add_Click( { ShowConsole $MyScriptPath = $This.MyScriptPath #Used to find proper path during click event Start-Process -FilePath 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe' -ArgumentList "-NoProfile -NoLogo -WindowStyle Hidden -ExecutionPolicy Bypass -File `"$MyScriptPath`"" -ErrorAction Stop HideConsole }) } if ($method -eq 'PSCommand') { $MenuItem.Add_Click( { ShowConsole $MyScriptPath = $This.MyScriptPath #Used to find proper path during click event Start-Process -FilePath 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe' -ArgumentList "-NoProfile -NoLogo -ExecutionPolicy Bypass -Command `"& {$MyScriptPath}""" -ErrorAction Stop HideConsole }) } if ($method -eq 'Other') { $MenuItem.Add_Click( { ShowConsole $MyScriptPath = $This.MyScriptPath #Used to find proper path during click event Start-Process $MyScriptPath HideConsole }) } } #Return our new MenuItem $MainMenu.MenuItems.AddRange($MenuItem) } function NMainMenu { param( [string]$Text = 'Placeholder Text', [switch]$AddExit = $false ) $MainMenu = New-Object System.Windows.Forms.MenuItem $MainMenu.Text = $Text $Systray_Tool_Icon.contextMenu.MenuItems.AddRange($MainMenu) $MainMenu if ($AddExit) { $Menu_Exit = New-Object System.Windows.Forms.MenuItem $Menu_Exit.Text = 'Exit' $Menu_Exit.add_Click( { $Systray_Tool_Icon.Visible = $false $window.Close() # $window_Config.Close() Stop-Process $pid }) $Systray_Tool_Icon.contextMenu.MenuItems.AddRange($Menu_Exit) } } $config = Import-Csv -Path $ConfigFilePath foreach ($main in ($config.mainmenu | Get-Unique)) { $tmpmenu = NMainMenu -Text $main $config | Where-Object { $_.Mainmenu -like $main } | ForEach-Object { NMenuItem -Text $_.ScriptName -MyScriptPath $_.ScriptPath -method $_.mode -MainMenu $tmpmenu } } $Menu_Exit = New-Object System.Windows.Forms.MenuItem $Menu_Exit.Text = 'Exit' $Menu_Exit.add_Click( { $Systray_Tool_Icon.Visible = $false $window.Close() $window_Config.Close() Stop-Process $pid }) $Systray_Tool_Icon.contextMenu.MenuItems.AddRange($Menu_Exit) # Create an application context for it to all run within. # This helps with responsiveness, especially when clicking Exit. HideConsole $appContext = New-Object System.Windows.Forms.ApplicationContext [void][System.Windows.Forms.Application]::Run($appContext) } } #end Function Export-ModuleMember -Function Start-PSSysTray #endregion #endregion |