Shortcuts.psm1
Set-StrictMode -Version Latest function Get-Shortcut { <# .SYNOPSIS This function searches for files matching a LNK and URL extension. .DESCRIPTION This function, by default, recursively searches for files matching a LNK and URL extensions containing a specific string inside the target path, name or both. If no folder path specified, it will recursively search all user profiles and the all users profile. .NOTES Created on: 6/23/2014 Created by: Adam Bertram .EXAMPLE Get-Shortcut -MatchingTargetPath 'http:\\servername\local' This example would find all shortcuts (URL and LNK) in all user profiles that have a target path that match 'http:\\servername\local' .EXAMPLE Get-Shortcut -MatchingTargetPath 'http:\\servername\local' -MatchingName 'name' This example would find all shortcuts (URL and LNK) in all user profiles that have a target path that match 'http:\\servername\local' and have a name containing the string "name" .EXAMPLE Get-Shortcut -MatchingTargetPath 'http:\\servername\local' -MatchingFilePath 'C:\Users\abertram\Desktop' This example would find all shortcuts (URL and LNK) in the 'C:\Users\abertram\Desktop file path that have a target path that match 'http:\\servername\local' and have a name containing the string "name" .PARAMETER MatchingTargetPath The string you'd like to search for inside the shortcut's target path .PARAMETER MatchingName A string you'd like to search for inside of the shortcut's name .PARAMETER MatchingFilePath A string you'd like to search for inside of the shortcut's file path .PARAMETER FolderPath The folder path to search for shortcuts in. You can specify multiple folder paths. This defaults to the user profile root and the all users profile .PARAMETER NoRecurse This turns off recursion on the folder path specified searching subfolders of the FolderPath #> [OutputType([System.IO.FileInfo])] [CmdletBinding()] param ( [string]$MatchingTargetPath, [string]$MatchingName, [string]$MatchingFilePath, [string[]]$FolderPath, [switch]$NoRecurse ) process { try { if (-not $FolderPath) { $FolderPath = (Get-RootUserProfileFolderPath), (Get-AllUsersProfileFolderPath) } $Params = @{ 'Include' = @('*.url', '*.lnk'); 'ErrorAction' = 'SilentlyContinue'; 'ErrorVariable' = 'MyError'; 'Force' = $true } if (-not $NoRecurse) { $Params['Recurse'] = $true } $ShellObject = New-Object -ComObject Wscript.Shell [System.Collections.ArrayList]$Shortcuts = @() foreach ($Path in $FolderPath) { try { Write-Log -Message "Searching for shortcuts in $Path..." [System.Collections.ArrayList]$WhereConditions = @() $Params['Path'] = $Path if ($MatchingTargetPath) { $WhereConditions.Add('(($ShellObject.CreateShortcut($_.FullName)).TargetPath -like "*$MatchingTargetPath*")') | Out-Null } if ($MatchingName) { $WhereConditions.Add('($_.Name -like "*$MatchingName*")') | Out-Null } if ($MatchingFilePath) { $WhereConditions.Add('($_.FullName -like "*$MatchingFilePath*")') | Out-Null } if ($WhereConditions.Count -gt 0) { $WhereBlock = [scriptblock]::Create($WhereConditions -join ' -and ') ## TODO: Figure out a way to make this cleanly log access denied errors and continue Get-ChildItem @Params | Where-Object $WhereBlock } else { Get-ChildItem @Params } Write-Log -Message "Finished searching for shortcuts in $Path..." } catch { Write-Log -Message "Error: $($_.Exception.Message) - Line Number: $($_.InvocationInfo.ScriptLineNumber)" -LogLevel '3' $PSCmdlet.ThrowTerminatingError($_) } } } catch { Write-Log -Message "Error: $($_.Exception.Message) - Line Number: $($_.InvocationInfo.ScriptLineNumber)" -LogLevel '3' $PSCmdlet.ThrowTerminatingError($_) } } } function New-Shortcut { <# .SYNOPSIS This function creates a file shortcut .NOTES Created on: 07/19/2014 Created by: Adam Bertram .EXAMPLE New-Shortcut -FolderPath 'C:\' -Name 'My Shortcut' -TargetFilePath 'C:\Windows\notepad.exe' This examples creates a shortcut in C:\ called 'My Shortcut.lnk' pointing to notepad.exe .EXAMPLE New-Shortcut -CommonLocation AllUsersDesktop -Name 'My Shortcut' -TargetFilePath 'C:\Windows\notepad.exe' This examples creates a shortcut on the all users desktop called 'My Shortcut.lnk' pointing to notepad.exe .PARAMETER FolderPath If a custom path is needed that's not included in the list of common locations in the CommonLocation parameter this parameter can be used to create a folder in the specified path. .PARAMETER CommonLocation This is a set of common locations shortcuts are typically created in. Use this parameter if you'd like to quickly specify where the shortcut needs to be created in. .PARAMETER Name The name of the shortcut (file) .PARAMETER TargetPath The file path or URL of the application you'd like the shortcut to point to .PARAMETER Arguments File arguments you'd like to append to the target file path #> [OutputType()] [CmdletBinding(SupportsShouldProcess,DefaultParameterSetName = 'CommonLocation')] param ( [Parameter(ParameterSetName = 'CustomLocation', Mandatory = $true)] [ValidateScript({ Test-Path $_ -PathType 'Container' })] [string]$FolderPath, [Parameter(ParameterSetName = 'CommonLocation', Mandatory = $true)] [ValidateSet('AllUsersDesktop')] [string]$CommonLocation, [Parameter(Mandatory = $true)] [string]$Name, [Parameter(Mandatory = $true)] [string]$TargetPath, [Parameter()] [string]$Arguments ) begin { try { $ShellObject = New-Object -ComObject Wscript.Shell } catch { Write-Log -Message "Error: $($_.Exception.Message) - Line Number: $($_.InvocationInfo.ScriptLineNumber)" -LogLevel '3' $PSCmdlet.ThrowTerminatingError($_) } } process { try { if ($TargetPath -notmatch '^\w{1}:\\') { $Extension = 'url' } else { $Extension = 'lnk' } if ($CommonLocation -eq 'AllUsersDesktop') { $FilePath = "$(Get-AllUsersDesktopFolderPath)\$Name.$Extension" } elseif ($FolderPath) { $FilePath = "$FolderPath\$Name.$Extension" } if (Test-Path -Path $FilePath -PathType Leaf) { throw "$FilePath already exists. New shortcut cannot be made here." } $Object = $ShellObject.CreateShortcut($FilePath) $Object.TargetPath = $TargetPath if ($TargetPath -notmatch '^\w{1}:\\') { $Extension = 'url' } else { $Extension = 'lnk' $Object.Arguments = $Arguments $Object.WorkingDirectory = ($TargetFilePath | Split-Path -Parent) } if ($PSCmdlet.ShouldProcess($FilePath,'New shortcut')) { Write-Log -Message "Creating shortcut at $FilePath using targetpath $TargetPath" $Object.Save() if (Test-Path -Path $FilePath -PathType Leaf) { Write-Log -Message "Shortcut at $FilePath was successfully created" } } } catch { Write-Log -Message "Error: $($_.Exception.Message) - Line Number: $($_.InvocationInfo.ScriptLineNumber)" -LogLevel '3' $PSCmdlet.ThrowTerminatingError($_) } } } |