Today I needed to create a shortcut for a program in a package. not that big a challenge I thought, as I have created lots of shortcuts during my 16 years deploying Windows and related software. But then the customer said ”oh, can you set the Run as Administrator flag on that?”.

Well, never had to do that before but it turns out that PowerShell once again comes to the rescue!

We can create the shortcut like we normally do, using the WScript.Shell.CreateShortcut method, and the using the System.IO.FileStream to modify the bitstream on the shortcut that controls the elevation prompt.

The following script contains a PowerShell cmdlet that will create shortcuts with or without elevation (Run as Administrator). The last line contains the call to the cmdlet that creates a shortcut for Notepad++ that will have the Run as Administrator flag set.

CreateShortcut -name "Notepad++ Admin" -Target "${env:ProgramFiles(x86)}\Notepad++\notepad++.exe" -OutputDirectory "C:\Users\Public\Desktop" -Elevated True

2014-12-16 14_13_19-2014-12-16 14_13_31-Notepad Admin Properties2014-12-16 14_13_49-Advanced Properties

The script

Function CreateShortcut
{
    [CmdletBinding()]
    param (    
        [parameter(Mandatory=$true)]
        [ValidateScript( {[IO.File]::Exists($_)} )]
        [System.IO.FileInfo] $Target,
    
        [ValidateScript( {[IO.Directory]::Exists($_)} )]
        [System.IO.DirectoryInfo] $OutputDirectory,
    
        [string] $Name,
        [string] $Description,
    
        [string] $Arguments,
        [System.IO.DirectoryInfo] $WorkingDirectory,
    
        [string] $HotKey,
        [int] $WindowStyle = 1,
        [string] $IconLocation,
        [switch] $Elevated
    )

    try {
        #region Create Shortcut
        if ($Name) {
            [System.IO.FileInfo] $LinkFileName = [System.IO.Path]::ChangeExtension($Name, "lnk")
        } else {
            [System.IO.FileInfo] $LinkFileName = [System.IO.Path]::ChangeExtension($Target.Name, "lnk")
        }
    
        if ($OutputDirectory) {
            [System.IO.FileInfo] $LinkFile = [IO.Path]::Combine($OutputDirectory, $LinkFileName)
        } else {
            [System.IO.FileInfo] $LinkFile = [IO.Path]::Combine($Target.Directory, $LinkFileName)
        }

       
        $wshshell = New-Object -ComObject WScript.Shell
        $shortCut = $wshShell.CreateShortCut($LinkFile) 
        $shortCut.TargetPath = $Target
        $shortCut.WindowStyle = $WindowStyle
        $shortCut.Description = $Description
        $shortCut.WorkingDirectory = $WorkingDirectory
        $shortCut.HotKey = $HotKey
        $shortCut.Arguments = $Arguments
        if ($IconLocation) {
            $shortCut.IconLocation = $IconLocation
        }
        $shortCut.Save()
        #endregion

        #region Elevation Flag
        if ($Elevated) {
            $tempFileName = [IO.Path]::GetRandomFileName()
            $tempFile = [IO.FileInfo][IO.Path]::Combine($LinkFile.Directory, $tempFileName)
        
            $writer = new-object System.IO.FileStream $tempFile, ([System.IO.FileMode]::Create)
            $reader = $LinkFile.OpenRead()
        
            while ($reader.Position -lt $reader.Length)
            {        
                $byte = $reader.ReadByte()
                if ($reader.Position -eq 22) {
                    $byte = 34
                }
                $writer.WriteByte($byte)
            }
        
            $reader.Close()
            $writer.Close()
        
            $LinkFile.Delete()
        
            Rename-Item -Path $tempFile -NewName $LinkFile.Name
        }
        #endregion
    } catch {
        Write-Error "Failed to create shortcut. The error was '$_'."
        return $null
    }
    return $LinkFile
}

CreateShortcut -name "Notepad++ Admin" -Target "${env:ProgramFiles(x86)}\Notepad++\notepad++.exe" -OutputDirectory "C:\Users\Public\Desktop" -Elevated True

 

Download the script here: [download id=”227″]