PSCommander.psm1
function New-CommanderToolbarIcon { <# .SYNOPSIS Creates a notification tray toolbar icon. .DESCRIPTION Creates a notification tray toolbar icon. .PARAMETER Text Text to display when the icon is hovered. .PARAMETER MenuItem Menu items to display when the icon is right clicked. .PARAMETER LoadMenuItems A script block to call to dynamically load menu items. .PARAMETER HideExit Hides the exit menu item. .PARAMETER HideConfig Hides the config menu item. .EXAMPLE New-CommanderToolbarIcon -MenuItem @( New-CommanderMenuItem -Text 'Notepad' -Action { Start-Process notepad } -MenuItem @( New-CommanderMenuItem -Text 'Subnotepad' -Action { Start-Process notepad } ) -LoadMenuItems { New-CommanderMenuItem -Text 'Dynamic SubNotepad' -Action { Start-Process notepad } } ) -LoadMenuItems { New-CommanderMenuItem -Text 'Dynamic Notepad' -Action { Start-Process notepad } } Creates a tool bar icon with several menu items. #> [CmdletBinding()] param( [Parameter()] [string]$Text, [Parameter()] [pscommander.MenuItem[]]$MenuItem, [Parameter()] [ScriptBlock]$LoadMenuItems, [Parameter()] [Switch]$HideExit, [Parameter()] [Switch]$HideConfig ) Process { $ToolbarIcon = [pscommander.ToolbarIcon]::new() $ToolbarIcon.Text = $Text $ToolbarIcon.MenuItems = $MenuItem $ToolbarIcon.LoadItems = $LoadMenuItems $ToolbarIcon.HideExit = $HideExit $ToolbarIcon.HideConfig = $HideConfig $ToolbarIcon } } function New-CommanderMenuItem { <# .SYNOPSIS Creates a new menu item to use within a toolbar notification icon. .DESCRIPTION Creates a new menu item to use within a toolbar notification icon. .PARAMETER Text The text to display for this menu item. .PARAMETER Action A script block to invoke when the menu item is clicked. .PARAMETER MenuItem Child menu items to display. .PARAMETER LoadMenuItems Child menu items to load dynamically. #> [CmdletBinding()] param( [Parameter()] [string]$Text, [Parameter()] [ScriptBlock]$Action, [Parameter()] [pscommander.MenuItem[]]$MenuItem, [Parameter()] [ScriptBlock]$LoadMenuItems ) Process { $mi = [pscommander.MenuItem]::new() $mi.Text = $Text $mi.Action = $Action $mi.Children = $MenuItem $mi.LoadChildren = $LoadMenuItems $mi } } function New-CommanderHotKey { <# .SYNOPSIS Creates a new global hot key binding. .DESCRIPTION Creates a new global hot key binding. .PARAMETER ModifierKey One or modifier keys to use for this hot key. .PARAMETER Key The main key to use for this hot key. .PARAMETER Action The action to invoke for this hot key. .EXAMPLE New-CommanderHotKey -Key 'T' -ModifierKey 'Ctrl' -Action { Start-Process notepad } Starts notepad when Ctrl+T is pressed. #> [CmdletBinding()] param( [Parameter()] [pscommander.ModifierKeys]$ModifierKey, [Parameter(Mandatory)] [pscommander.Keys]$Key, [Parameter(Mandatory)] [ScriptBlock]$Action ) $HotKey = [pscommander.HotKey]::new() $HotKey.Id = Get-Random $HotKey.ModifierKeys = $ModifierKey $HotKey.Keys = $Key $HotKey.Action = $Action $HotKey } function New-CommanderSchedule { <# .SYNOPSIS Creates a scheduled action based on a CRON expression. .DESCRIPTION Creates a scheduled action based on a CRON expression. .PARAMETER Action The action to execute on the schedule. .PARAMETER CronExpression The CRON expression that defines when to run the action. .EXAMPLE New-CommanderSchedule -CronExpression "* * * * *" -Action { Start-Process Notepad } Starts notepad every minute. #> [CmdletBinding()] param( [Parameter()] [ScriptBlock]$Action, [Parameter()] [string]$CronExpression ) $Schedule = [pscommander.Schedule]::new() $Schedule.Action = $Action $Schedule.Cron = $CronExpression $Schedule } function New-CommanderContextMenu { <# .SYNOPSIS Creates a context menu item that executes PowerShell. .DESCRIPTION Creates a context menu item that executes PowerShell. .PARAMETER Action The script block action to execute. $Args[0] will include the path the was right clicked. .PARAMETER Text The text to display. .PARAMETER Location The location to display this context menu item. File will display this action when right clicking on the associated file extension. FolderLeftPane will display when right clicking on a folder in the left pane of the explorer window. FolderRightPane will display when right clicking on the folder in the right pane of the explorer window or the desktop. .PARAMETER Extension The extension to associate this context menu item to. This requires that Location is set to File. .PARAMETER DisplayOnShiftClick Displays this option only when shift is help down during the right click. .PARAMETER Position The location to position this context menu item. You can select Top, Bottom and None. None is the default. .PARAMETER Icon An icon to display for this context menu item. .PARAMETER IconIndex The index within the icon file to use. .EXAMPLE New-CommanderContextMenu -Text 'Click me' -Action { Start-Process code -ArgumentList $args[0] } Starts VS Code and opens the file that was right clicked. #> [CmdletBinding()] param( [Parameter(Mandatory)] [ScriptBlock]$Action, [Parameter(Mandatory)] [string]$Text, [Parameter()] [ValidateSet("FolderLeftPanel", "FolderRightPanel", "File")] [string]$Location = "File", [Parameter()] [string]$Extension = "*", [Parameter()] [Switch]$DisplayOnShiftClick, [Parameter()] [ValidateSet("Top", "Bottom", "None")] [string]$Position = 'None', [Parameter()] [string]$Icon, [Parameter()] [int]$IconIndex ) $ContextMenu = [pscommander.ExplorerContextMenu]::new() $ContextMenu.Id = Get-Random $ContextMenu.Action = $Action $ContextMenu.Text = $Text $ContextMenu.Location = $Location $ContextMenu.Extension = $Extension $ContextMenu.Extended = $DisplayOnShiftClick $ContextMenu.Position = $Position $ContextMenu.Icon = $Icon $ContextMenu.IconIndex = $IconIndex $ContextMenu } function New-CommanderFileAssociation { <# .SYNOPSIS Creates a file association that will invoke the action when it's opened. .DESCRIPTION Creates a file association that will invoke the action when it's opened. .PARAMETER Extension The extension to associate with the action. .PARAMETER Action The action to execute when the file type is opened. $Args[0] will be the full file name of the file opened. .EXAMPLE New-CommanderFileAssociation -Extension ".ps2" -Action { Start-Process code -ArgumentList $Args[0] } Starts VS Code and opens the opened PS2 file. #> [CmdletBinding()] param( [Parameter(Mandatory)] [string]$Extension, [Parameter(Mandatory)] [scriptblock]$Action ) if (-not $Extension.StartsWith('.')) { throw "Extension needs to start with '.'" } $FileAssociation = [pscommander.FileAssociation]::new() $FileAssociation.Id = Get-Random $FileAssociation.Extension = $Extension $FileAssociation.Action = $Action $FileAssociation } function New-CommanderShortcut { <# .SYNOPSIS Creates a new desktop shortcut that will run the action. .DESCRIPTION Creates a new desktop shortcut that will run the action. .PARAMETER Text The text to display on the desktop. .PARAMETER Description The description shown when hovering the shortcut. .PARAMETER Icon The icon to display. .PARAMETER Action The action to execute when the shortcut is clicked. .EXAMPLE New-CommanderShortcut -Text 'Click Me' -Description 'Nice' -Action { Start-Process notepad } Creates a shortcut that will start notepad when clicked. #> [CmdletBinding()] param( [Parameter(Mandatory)] [string]$Text, [Parameter()] [string]$Description, [Parameter()] [string]$Icon, [Parameter(Mandatory)] [ScriptBlock]$Action ) $Shortcut = [pscommander.Shortcut]::new() $Shortcut.Id = Get-Random $Shortcut.Text = $Text $Shortcut.Description = $Description $Shortcut.Icon = $Icon $Shortcut.Action = $Action $Shortcut } function Start-Commander { <# .SYNOPSIS Starts PSCommander. .DESCRIPTION Starts PSCommander .EXAMPLE Start-Commander Starts PSCommander #> $Documents = [System.Environment]::GetFolderPath('MyDocuments') $ConfigPath = [IO.Path]::Combine($Documents, 'PSCommander', 'config.ps1') if (-not (Test-Path $ConfigPath)) { Write-Warning "Configuration file for PSCommander not found. Creating config file..." New-Item -Path (Join-Path $Documents 'PSCommander') -ItemType Directory -Force -ErrorAction SilentlyContinue | Out-Null "New-CommanderToolbarIcon -MenuItem @( New-CommanderMenuItem -Text 'Documentation' -Action { Start-Process 'https://docs.poshtools.com/powershell-pro-tools-documentation/pscommander' } )" | Out-File $ConfigPath Start-Process -FilePath "$PSScriptRoot\psscriptpad.exe" -ArgumentList @("-c `"$ConfigPath`"") } Start-Process (Join-Path $PSScriptRoot "PSCommander.exe") } function Install-Commander { <# .SYNOPSIS Sets commander to run on logon. .DESCRIPTION Sets commander to run on logon. .EXAMPLE Install-Commander Sets commander to run on logon. #> New-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" -Name 'PSCommander' -Value (Join-Path $PSScriptRoot "pscommander.exe") -Force | Out-Null } function Uninstall-Commander { <# .SYNOPSIS Stops commander from running on logon. .DESCRIPTION Stops commander from running on logon. .EXAMPLE Uninstall-Commander Stops commander from running on logon. #> Remove-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" -Name 'PSCommander' } function Install-CommanderLicense { <# .SYNOPSIS Installs a PowerShell Pro Tools license to use with PSCommander. .DESCRIPTION Installs a PowerShell Pro Tools license to use with PSCommander. You will need to restart PSCommander after installing the license. .PARAMETER Path The path to the PowerShell Pro Tools license. .EXAMPLE Install-CommanderLicense -Path .\license.txt Installs the PSCommander license. #> [CmdletBinding()] param( [Parameter(Mandatory)] [string]$Path ) if (-not (Test-Path $Path)) { throw "File not found" } $Content = Get-Content $Path -Raw $Folder = Join-Path $env:appdata "PowerShell Pro Tools" if (-not (Test-Path $Folder)) { New-Item -Path $Folder -ItemType 'Directory' } $Content | Out-File (Join-Path $Folder "license.lic") } |