Comment créer des raccourcis sur le bureau avec PowerShell : le guide étape par étape

La création de raccourcis de bureau de façon programmée peut faire gagner beaucoup de temps et d’efforts aux professionnels de l’informatique, en particulier lorsqu’ils gèrent des environnements à utilisateurs multiples. PowerShell, un puissant langage de script natif de Windows, offre la flexibilité et la fonctionnalité nécessaires pour automatiser efficacement cette tâche.

Ce billet de blog se penche sur un script PowerShell complet conçu pour créer des raccourcis de bureau pour les exécutables, en détaillant son utilisation, ses fonctionnalités et ses avantages pour les professionnels de l’informatique et les fournisseurs de services gérés (MSP).

Contexte

Dans les grands environnements informatiques, la gestion des postes de travail des utilisateurs et la garantie d’une uniformité entre tous les systèmes peuvent constituer un défi. Les raccourcis du bureau sont un élément simple mais essentiel de cette gestion, car ils permettent d’accéder rapidement aux applications, aux sites web et aux fichiers.

La création manuelle de ces raccourcis pour chaque utilisateur n’est pas possible, en particulier dans les entreprises comptant de nombreux utilisateurs. C’est là que l’automatisation à l’aide de scripts PowerShell devient inestimable. Le script en question ne se contente pas de créer des raccourcis, il permet également de les personnaliser à l’aide de paramètres tels que les chemins d’accès aux icônes, les arguments exécutables et les paramètres spécifiques à l’utilisateur.

Le script

<#
.SYNOPSIS
    This script creates a desktop shortcut for an executable with specified options. It can create a shortcut for all users (including new ones) or for existing users only.
.DESCRIPTION
    This script creates a desktop shortcut for an executable with specified options. 
    It can create a shortcut for all users (including new ones) or for existing users only.

    You can also provide a base64 string on line 79 enclosed in quotes and an icon directory, and the script will use that instead.
.EXAMPLE
    This will create a shortcut that opens www.google.com in Firefox on JohnSmith's desktop. This is not limited to just browsers; you can specify any executable you would normally be able to via the "Create Shortcut" menu.
    
    -Name "ERP App" -EXEPath "C:\Program Files\Mozilla Firefox\firefox.exe" -StartIn "C:\Program Files\Mozilla Firefox" -IconPath "C:\ProgramData\ERPapp\customicon.ico" -Arguments "https://www.google.com" -User "JohnSmith"

    Creating Shortcut at C:\Users\JohnSmith\Desktop\ERP App.lnk

.PARAMETER NAME
    The name of the shortcut, e.g., "Login Portal".

.PARAMETER ExePath
    The target field in the shortcut, excluding arguments.

.PARAMETER Arguments
    The arguments for the executable inside the shortcut.

.PARAMETER StartIn
    Some executables require that they be opened in a specific directory.

.PARAMETER Icon
    The path to an image file to use for the shortcut. You could also place the base64 string on line 79 and specify an IconDirectory with the below parameter.

.PARAMETER IconDirectory
    Path to store the .ico file to use for the shortcut.

.PARAMETER IconURL
    A link to an image file you would like to use for the shortcut. You could also place the base64 string on line 79 and specify an IconDirectory using '-IconDirectory'.

.PARAMETER AllExistingUsers
    Creates the shortcut for all existing users but not for new users, e.g., C:\Users\*\Desktop\shortcut.lnk.

.PARAMETER AllUsers
    Creates the shortcut in C:\Users\Public\Desktop.

.OUTPUTS
    None
.NOTES
    Minimum OS Architecture Supported: Windows 7, Windows Server 2008
    Release Notes: Split the script into three separate scripts, added script variable support, and improved icon support.
By using this script, you indicate your acceptance of the following legal terms as well as our Terms of Use at https://www.ninjaone.com/terms-of-use.
    Ownership Rights: NinjaOne owns and will continue to own all right, title, and interest in and to the script (including the copyright). NinjaOne is giving you a limited license to use the script in accordance with these legal terms. 
    Use Limitation: You may only use the script for your legitimate personal or internal business purposes, and you may not share the script with another party. 
    Republication Prohibition: Under no circumstances are you permitted to re-publish the script in any script library or website belonging to or under the control of any other software provider. 
    Warranty Disclaimer: The script is provided “as is” and “as available”, without warranty of any kind. NinjaOne makes no promise or guarantee that the script will be free from defects or that it will meet your specific needs or expectations. 
    Assumption of Risk: Your use of the script is at your own risk. You acknowledge that there are certain inherent risks in using the script, and you understand and assume each of those risks. 
    Waiver and Release: You will not hold NinjaOne responsible for any adverse or unintended consequences resulting from your use of the script, and you waive any legal or equitable rights or remedies you may have against NinjaOne relating to your use of the script. 
    EULA: If you are a NinjaOne customer, your use of the script is subject to the End User License Agreement applicable to you (EULA).
#>

[CmdletBinding()]
param (
    [Parameter()]
    [String]$Name,
    [Parameter()]
    [String]$ExePath,
    [Parameter()]
    [String]$Arguments,
    [Parameter()]
    [String]$StartIn,
    [Parameter()]
    [String]$Icon,
    [Parameter()]
    [String]$IconDirectory,
    [Parameter()]
    [String]$IconUrl,
    [Parameter()]
    [Switch]$AllExistingUsers,
    [Parameter()]
    [String]$ExcludeUsers,
    [Parameter()]
    [Switch]$AllUsers
)

begin {
    Add-Type -AssemblyName System.Drawing

    # If the line below is replaced with $IconBase64 = 'YourBase64EncodedImageInQuotes', the script will decode it and use it for the desktop shortcut. Be sure to provide an Icon Storage Directory.
    $IconBase64 = $null

    # Replace existing parameters with Form Variables if used.
    if ($env:shortcutName -and $env:shortcutName -notlike "null") { $Name = $env:shortcutName }
    if ($env:createTheShortcutFor -and $env:createTheShortcutFor -notlike "null") { 
        if ($env:createTheShortcutFor -eq "All Users") { $AllUsers = $True }
        if ($env:createTheShortcutFor -eq "All Existing Users") { $AllExistingUsers = $True }
    }
    if ($env:exePath -and $env:exePath -notlike "null") { $ExePath = $env:exePath }
    if ($env:exeArguments -and $env:exeArguments -notlike "null") { $Arguments = $env:exeArguments }
    if ($env:exeShouldStartIn -and $env:exeShouldStartIn -notlike "null") { $StartIn = $env:exeShouldStartIn }
    if ($env:linkToIconFile -and $env:linkToIconFile -notlike "null") { $IconUrl = $env:linkToIconFile }
    if ($env:iconStorageDirectory -and $env:iconStorageDirectory -notlike "null") { $IconDirectory = $env:iconStorageDirectory }

    # Ensure a user is specified for shortcut creation.
    if (-not $AllUsers -and -not $AllExistingUsers -and -not $User) {
        Write-Host "[Error] You must specify which desktop to create the shortcut on!"
        exit 1
    }

    $invalidFileNames = '[<>:"/\\|?*\x00-\x1F]|\.$|\s$'
    if ($Name -match $invalidFileNames) {
        Write-Host '[Error] The name you specified contains one of the following invalid characters or ends with a period. <>:"/\|?*'
        exit 1
    }

    $ExitCode = 0
    
    # Icons are secondary. If no information is given, continue without them, but notify the technician.
    if (($Icon -or $IconUrl) -and -not $IconDirectory) {
        Write-Warning "An icon was provided, but no storage location was specified. Use the Icon Storage Directory parameter to specify a directory to store it. (You may want this directory to be accessible by all users.)"
        Write-Warning "Ignoring supplied icon info."
        $ExitCode = 1
        $Icon = $null
        $IconUrl = $null
    }

    if ($Icon) {
        $FileName = Split-Path $Icon -Leaf

        # Check for valid icon formats. Only support .png, .jpg, .jpeg, .ico, and .gif.
        if ($FileName -notmatch '\.bmp$' -and $FileName -notmatch '\.png$' -and $FileName -notmatch '\.jpg$' -and $FileName -notmatch '\.jpeg$' -and $FileName -notmatch '.ico$' -and $FileName -notmatch '.gif$') {
            Write-Warning "Your icon is in an invalid format. Only .png, .jpg, .jpeg, .ico, and .gif formats are supported. Switching to the default icon. You can re-run the script to replace the icon."
            $Icon = $null
        }

        if (-not (Test-Path $Icon -ErrorAction SilentlyContinue)) {
            Write-Warning "It looks like your icon is missing. Skipping for now; re-run the script with a valid path to add the icon."
            $Icon = $null
        }
    }

    # Create the directory for the icon if it doesn't exist.
    if ($IconDirectory -and -not (Test-Path $IconDirectory -ErrorAction SilentlyContinue)) {
        New-Item -ItemType Directory -Path $IconDirectory | Out-Null
    }

    # For PowerShell 2.0 and 3.0 compatibility we're going to need to create a Get-FileHash function
    if ($PSVersionTable.PSVersion.Major -lt 4) {
        function Get-FileHash {
            param (
                [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
                [string[]]$Path,
                [Parameter(Mandatory = $false)]
                [ValidateSet("SHA1", "SHA256", "SHA384", "SHA512", "MD5")]
                [string]$Algorithm = "SHA256"
            )
            $Path | ForEach-Object {
                # Only hash files that exist
                $CurrentPath = $_
                if ($(Test-Path -Path $CurrentPath -ErrorAction SilentlyContinue)) {
                
                    $HashAlgorithm = [System.Security.Cryptography.HashAlgorithm]::Create($Algorithm)
                    $Hash = [System.BitConverter]::ToString($hashAlgorithm.ComputeHash([System.IO.File]::ReadAllBytes($CurrentPath)))
                    @{
                        Algorithm = $Algorithm
                        Path      = $Path
                        Hash      = $Hash.Replace('-', '')
                    }
                }
            }
        }
    }

    # Convert a Base64 string to a file.
    function ConvertFrom-Base64 {
        param(
            $Base64,
            $Path
        )
        $bytes = [Convert]::FromBase64String($Base64)

        [IO.File]::WriteAllBytes($Path, $bytes)
    }

    # Utility function for downloading files.
    function Invoke-Download {
        param(
            [Parameter()]
            [String]$URL,
            [Parameter()]
            [String]$BaseName,
            [Parameter()]
            [int]$Attempts = 3,
            [Parameter()]
            [Switch]$SkipSleep
        )

        # In case 'https://' is omitted from the URL.
        if ($URL -notmatch "^http(s)?://") {
            Write-Warning "http(s):// is required to download the file. Adding https:// to your input...."
            $URL = "https://$URL"
            Write-Warning "New Url $URL."
        }
    
        Write-Host "Downloading using $URL"

        $SupportedTLSversions = [enum]::GetValues('Net.SecurityProtocolType')
        if ( ($SupportedTLSversions -contains 'Tls13') -and ($SupportedTLSversions -contains 'Tls12') ) {
            [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol::Tls13 -bor [System.Net.SecurityProtocolType]::Tls12
        }
        elseif ( $SupportedTLSversions -contains 'Tls12' ) {
            [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12
        }
        else {
            # Not everything requires TLS 1.2, but we'll try anyways.
            Write-Warning "TLS 1.2 and or TLS 1.3 isn't supported on this system. This download may fail!"
            if ($PSVersionTable.PSVersion.Major -lt 3) {
                Write-Warning "PowerShell 2 / .NET 2.0 doesn't support TLS 1.2."
            }
        }

        $i = 1
        While ($i -le $Attempts) {
            # Some cloud services have rate-limiting
            if (-not ($SkipSleep)) {
                $SleepTime = Get-Random -Minimum 3 -Maximum 15
                Write-Host "Waiting for $SleepTime seconds."
                Start-Sleep -Seconds $SleepTime
            }
            if ($i -ne 1) { Write-Host "" }
            Write-Host "Download Attempt $i"

            try {
                # Invoke-WebRequest is preferred because it supports links that redirect, e.g., https://t.ly
                if ($PSVersionTable.PSVersion.Major -lt 4) {
                    # Figures out the type of file
                    $WebClient = New-Object System.Net.WebClient
                    $Response = $WebClient.OpenRead($Url)
                    $MimeType = $WebClient.ResponseHeaders["Content-Type"]
                    $DesiredExtension = switch -regex ($MimeType) {
                        "image/jpeg|image/jpg" { "jpg" }
                        "image/png" { "png" }
                        "image/gif" { "gif" }
                        "image/bmp|image/x-windows-bmp|image/x-bmp" { "bmp" }
                        "image/x-icon|image/vnd.microsoft.icon|application/ico" { "ico" }
                        default { 
                            throw "[Error] The URL you provided does not provide a supported image type. Image Types Supported: jpg, jpeg, ico, bmp, png and gif. Image Type detected: $MimeType"
                        }
                    }
                    # Downloads the file preserving the extension
                    $Path = "$BaseName.$DesiredExtension"
                    $WebClient.DownloadFile($URL, $Path)
                }
                else {
                    # Standard options
                    $WebRequestArgs = @{
                        Uri                = $URL
                        MaximumRedirection = 10
                        UseBasicParsing    = $true
                        Method             = "GET"
                    }

                    # Figures out the type of file
                    $Response = Invoke-WebRequest @WebRequestArgs
                    $MimeType = $Response.Headers.'Content-Type'
                    $DesiredExtension = switch -regex ($MimeType) {
                        "image/jpeg|image/jpg" { "jpg" }
                        "image/png" { "png" }
                        "image/gif" { "gif" }
                        "image/bmp|image/x-windows-bmp|image/x-bmp" { "bmp" }
                        "image/x-icon|image/vnd.microsoft.icon|application/ico" { "ico" }
                        default { 
                            throw "[Error] The URL you provided does not provide a supported image type. Image Types Supported: jpg, jpeg, ico, bmp, png and gif. Image Type detected: $MimeType"
                        }
                    }
                    # Define the path for saving the file
                    $Path = "$BaseName.$DesiredExtension"

                    # Save the content to the file
                    $Response.Content | Set-Content -Path $Path -Encoding Byte
                }

                $File = Test-Path -Path $Path -ErrorAction SilentlyContinue
            }
            catch {
                Write-Warning "An error has occurred while downloading!"
                Write-Warning $_.Exception.Message
                $_

                if ($Path -and (Test-Path -Path $Path -ErrorAction SilentlyContinue)) {
                    Remove-Item $Path -Force -Confirm:$false -ErrorAction SilentlyContinue
                }

                $File = $False
            }

            if ($File) {
                $i = $Attempts
            }
            else {
                Write-Warning "File failed to download. Check the link/URL and ensure it is correct, please note Ninja may have stripped out the following characters '&|;$><`!' from the link/URL."
                Write-Host ""
            }

            $i++
        }

        if ($Path -and -not (Test-Path $Path)) {
            Write-Warning "Failed to download file!"
        }
        else {
            return $Path
        }
    }

    # Convert an image to an icon file. This method creates a png and then forms an ico file by appending the png's binary.
    function ConvertFrom-Image {
        param(
            $ImagePath,
            $Path
        )

        # Grab an instance of the image and blank bitmap
        try {
            $image = [Drawing.Image]::FromFile($ImagePath)
        }
        catch [System.OutOfMemoryException] {
            Write-Host "[Error] Loading Image file is either an unsupported file, or to large to process."
            return
        }
        catch {
            Write-Host "[Error] $($_.Message)"
            return
        }

        # Resize the image to 255px by 255px while maintaining quality.
        # If you want transparency, you'll need an Alpha channel in the pixel format.
        $bitmap = New-Object System.Drawing.Bitmap (255, 255, [system.drawing.imaging.PixelFormat]::Format32bppArgb)
        $bitmap.SetResolution(255, 255)

        # Create a graphics object which will be used to resize the image to 255px by 255px
        $graphics = [System.Drawing.Graphics]::FromImage($bitmap)

        # Set some quality settings for the resize operation
        $graphics.SmoothingMode = [System.Drawing.Drawing2D.SmoothingMode]::HighQuality
        $graphics.InterpolationMode = [System.Drawing.Drawing2D.InterpolationMode]::HighQualityBicubic
        $graphics.PixelOffsetMode = [System.Drawing.Drawing2D.PixelOffsetMode]::HighQuality

        # Draw the image onto the bitmap
        $graphics.DrawImage($Image, 0, 0, 255, 255)
        
        # Temporarily save the image as a png
        $RandomNumber = Get-Random -Maximum 1000000
        $bitmap.Save("$env:TEMP\image-$RandomNumber.png", [System.Drawing.Imaging.ImageFormat]::Png)
        $png = "$env:TEMP\image-$RandomNumber.png"

        # Build the ico file using the png binary.
        if ($PSVersionTable.PSVersion.Major -gt 5) {
            $pngBytes = Get-Content -Path $png -AsByteStream
        }
        elseif ($PSVersionTable.PSVersion.Major -gt 2) {
            $pngBytes = Get-Content -Path $png -Encoding Byte -Raw
        }
        else {
            $pngBytes = [System.IO.File]::ReadAllBytes($png)
        }
        $icoHeader = [byte[]] @(0, 0, 1, 0, 1, 0)
        $imageDataSize = $pngBytes.Length
        $icoDirectory = [byte[]] @(
            255, 255, # icon size
            0, 0, # color count
            0, 0, # reserved
            0, 0, # hotspot x, hotspot y
            ($imageDataSize -band 0xFF),
            ([Math]::Floor($imageDataSize / [Math]::Pow(2, 8)) -band 0xFF),
            ([Math]::Floor($imageDataSize / [Math]::Pow(2, 16)) -band 0xFF),
            ([Math]::Floor($imageDataSize / [Math]::Pow(2, 24)) -band 0xFF),
            22, 0, 0, 0  # offset to image data
        )
        $iconData = $icoHeader + $icoDirectory + $pngBytes

        # Save the completed icon file and clean up any temporary files.
        if (Test-Path $Path -ErrorAction SilentlyContinue) { Remove-Item $Path -Force }
        [System.IO.File]::WriteAllBytes($Path, $iconData)

        if (Test-Path $png -ErrorAction SilentlyContinue) { Remove-Item $png -Force }
        $bitmap.Dispose()
        $image.Dispose()
        $graphics.Dispose()
        [System.GC]::Collect()

        # Refresh the icon cache depending on the OS version.
        if ([System.Environment]::OSVersion.Version.Major -ge 10) {
            Invoke-Command { ie4uinit.exe -show }
        }
        else {
            Invoke-Command { ie4uinit.exe -ClearIconCache }
        }
    }

    # Verify if the script is being run with elevated privileges.
    function Test-IsElevated {
        $id = [System.Security.Principal.WindowsIdentity]::GetCurrent()
        $p = New-Object System.Security.Principal.WindowsPrincipal($id)
        $p.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)
    }

    if (-not (Test-IsElevated)) {
        Write-Host -Object "[Error] Access Denied. Please run with Administrator privileges."
        exit 1
    }

    # Retrieve all registry paths for actual users (excluding system or network service accounts).
    function Get-UserHives {
        param (
            [Parameter()]
            [ValidateSet('AzureAD', 'DomainAndLocal', 'All')]
            [String]$Type = "All",
            [Parameter()]
            [String[]]$ExcludedUsers,
            [Parameter()]
            [switch]$IncludeDefault
        )

        # Different SID patterns for user account types: AzureAD, Domain, or Local.
        $Patterns = switch ($Type) {
            "AzureAD" { "S-1-12-1-(\d+-?){4}$" }
            "DomainAndLocal" { "S-1-5-21-(\d+-?){4}$" }
            "All" { "S-1-12-1-(\d+-?){4}$" ; "S-1-5-21-(\d+-?){4}$" } 
        }

        # Extract user profiles that match the SID patterns. 
        $UserProfiles = Foreach ($Pattern in $Patterns) { 
            Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\*" |
                Where-Object { $_.PSChildName -match $Pattern } | 
                Select-Object @{Name = "SID"; Expression = { $_.PSChildName } }, 
                @{Name = "UserHive"; Expression = { "$($_.ProfileImagePath)\NTuser.dat" } }, 
                @{Name = "UserName"; Expression = { "$($_.ProfileImagePath | Split-Path -Leaf)" } },
                @{Name = "Path"; Expression = { $_.ProfileImagePath } }
        }

        # Handle situations where information from the .Default user is required.
        switch ($IncludeDefault) {
            $True {
                $DefaultProfile = "" | Select-Object UserName, SID, UserHive, Path
                $DefaultProfile.UserName = "Default"
                $DefaultProfile.SID = "DefaultProfile"
                $DefaultProfile.Userhive = "$env:SystemDrive\Users\Default\NTUSER.DAT"
                $DefaultProfile.Path = "C:\Users\Default"

                $DefaultProfile | Where-Object { $ExcludedUsers -notcontains $_.UserName }
            }
        }

        $UserProfiles | Where-Object { $ExcludedUsers -notcontains $_.UserName }
    }

    # The actual shortcut creation
    function New-Shortcut {
        [CmdletBinding()]
        param(
            [Parameter()]
            [String]$Arguments,
            [Parameter()]
            [String]$IconPath,
            [Parameter(ValueFromPipeline = $True)]
            [String]$Path,
            [Parameter()]
            [String]$Target,
            [Parameter()]
            [String]$WorkingDir
        )
        process {
            Write-Host "Creating Shortcut at $Path"
            $ShellObject = New-Object -ComObject ("WScript.Shell")
            $Shortcut = $ShellObject.CreateShortcut($Path)
            $Shortcut.TargetPath = $Target
            if ($WorkingDir) { $Shortcut.WorkingDirectory = $WorkingDir }
            if ($Arguments) { $ShortCut.Arguments = $Arguments }
            if ($IconPath) { $Shortcut.IconLocation = $IconPath }
            $Shortcut.Save()

            if (-not (Test-Path $Path -ErrorAction SilentlyContinue)) {
                Write-Host "[Error] Unable to create Shortcut at $Path"
                exit 1
            }
        }
    }
}
process {
    $ShortcutPath = New-Object System.Collections.Generic.List[String]

    # Creating the filename's for the path
    if ($Url) { $File = "$Name.url"; $Target = $Url }
    if ($ExePath) { $File = "$Name.lnk"; $Target = $ExePath }
    if ($RDPTarget) { $File = "$Name.rdp" }

    # Grabing the excluded users
    if ($ExcludeUsers) { $ExcludedUsers = ($ExcludeUsers -split ",").trim() }

    # Building the path's and adding it to the ShortcutPath list
    if ($AllUsers) { $ShortcutPath.Add("$env:Public\Desktop\$File") }

    if ($AllExistingUsers) {
        $UserProfiles = Get-UserHives -ExcludedUsers $ExcludedUsers
        # Loop through each user profile
        $UserProfiles | ForEach-Object { $ShortcutPath.Add("$($_.Path)\Desktop\$File") }
    }

    if ($User) { 
        $UserProfile = Get-UserHives | Where-Object { $_.Username -like $User }
        $ShortcutPath.Add("$($UserProfile.Path)\Desktop\$File")
    }

    $ShortcutArguments = @{
        Target     = $Target
        WorkingDir = $StartIn
        Arguments  = $Arguments
    }

    # If we're given a url we'll want to download it
    if ($IconUrl) {
        $DownloadArguments = @{
            URL      = $IconUrl
            BaseName = "$IconDirectory\$Name"
        }
        if ($SkipSleep) { $DownloadArguments["SkipSleep"] = $True }

        $Icon = Invoke-Download @DownloadArguments
        if ($Icon -and -not (Test-Path $Icon -ErrorAction SilentlyContinue)) {
            $ExitCode = 1
            $Icon = $Null
            $IconUrl = $Null
        }
    }

    # This will convert the base64 into an image and save it to the temp folder
    if ($IconBase64 -and $IconDirectory -and -not $Icon -and -not $IconUrl) {
        Write-Verbose "Converting Icon base64 to original image and saving to $IconDirectory..."
        ConvertFrom-Base64 -Base64 $IconBase64 -Path "$IconDirectory\$Name.Png"
        $Icon = "$IconDirectory\$Name.Png"
    }

    if ($Icon -and (Get-Item -Path $Icon).Extension -notlike ".ico") {
        $FileHash = "$((Get-FileHash -Path $Icon -Algorithm MD5).Hash)"
        Write-Verbose "Converting image to icon and saving to $IconDirectory\$FileHash.ico ..."
        ConvertFrom-Image -ImagePath $Icon -Path "$IconDirectory\$FileHash.ico"
        Remove-Item -Path $Icon -Force
        $Icon = "$IconDirectory\$FileHash.ico"
    }
    elseif ($Icon -and (Test-Path $Icon -ErrorAction SilentlyContinue)) {
        $FileHash = "$((Get-FileHash -Path $Icon -Algorithm MD5).Hash)"
        Move-Item -Path $Icon -Destination "$IconDirectory\$FileHash.ico"
        $Icon = "$IconDirectory\$FileHash.ico"
    }

    if ($Icon -and (Test-Path $Icon -ErrorAction SilentlyContinue)) {
        $ShortcutArguments["IconPath"] = $Icon
    }
    elseif ($Icon) {
        $ExitCode = 1
    }

    $ShortcutPath | New-Shortcut @ShortcutArguments

    exit $ExitCode
}end {
    
    
    
}

 

Description détaillée

Synopsis et paramètres du script

La fonction principale du script PowerShell est de créer des raccourcis sur le bureau pour des exécutables avec des options spécifiques. Il permet de créer des raccourcis pour tous les utilisateurs, y compris les nouveaux, ou uniquement pour les utilisateurs existants. Voici un aperçu de ses paramètres et de ses fonctionnalités :

  • Nom: Le nom du raccourci, par exemple “Login Portal”.
  • ExePath: Chemin d’accès au fichier exécutable.
  • Arguments: Tout argument à transmettre à l’exécutable.
  • StartIn: Le répertoire dans lequel l’exécutable doit démarrer.
  • Icône: Chemin d’accès à un fichier image pour l’icône du raccourci.
  • IconDirectory: Répertoire dans lequel est stocké le fichier d’icônes.
  • IconURL: URL d’un fichier image pour l’icône du raccourci.
  • Tous les utilisateurs existants: Crée le raccourci pour tous les utilisateurs existants.
  • Tous les utilisateurs: Crée le raccourci pour tous les utilisateurs, y compris les nouveaux.
  • Exclure les utilisateurs: Liste des utilisateurs à exclure de la création de raccourcis.

Fonctionnalité du script

Configuration initiale

Le script commence par ajouter l’assemblage .NET nécessaire pour le dessin, qui est crucial pour la gestion des fichiers image. Il comprend également une section permettant de gérer les icônes encodées en base64, ce qui offre une certaine souplesse pour la création d’icônes dynamiques.

Traitement des paramètres

Les variables d’environnement peuvent remplacer les paramètres fournis, ce qui permet au script de s’adapter à différentes conditions d’exécution. Ceci est particulièrement utile dans les scénarios de déploiement automatisé.

Validation par l’utilisateur

Avant de poursuivre, le script vérifie qu’un utilisateur est spécifié pour la création de raccourcis. Cela permet d’éviter les erreurs et de s’assurer que le script cible les bons profils d’utilisateurs.

Traitement des icônes

Le script comprend une gestion robuste des icônes :

  • Il vérifie que les formats de fichiers sont valides.
  • Télécharge des icônes à partir d’URL si elles sont fournies.
  • Convertit les images encodées en base64 en fichiers d’icônes.
  • Convertit divers formats d’images en fichiers .ico si nécessaire.

Création de raccourcis

En utilisant l’objet COM WScript.Shell, le script crée des raccourcis avec les paramètres spécifiés. Il prend en charge plusieurs profils d’utilisateurs, y compris tous les utilisateurs existants ou tous les utilisateurs, en parcourant les répertoires d’utilisateurs.

Cas d’utilisation potentiels

Scénario du monde réel

Prenons l’exemple d’un service informatique d’une grande entreprise qui doit déployer un nouveau système ERP. L’équipe informatique peut utiliser ce script pour créer un raccourci pour l’application ERP sur le bureau de tous les utilisateurs. En spécifiant le chemin d’accès à l’exécutable, le répertoire de démarrage et l’icône personnalisée, l’équipe garantit une expérience utilisateur cohérente et professionnelle. La capacité du script à gérer plusieurs profils d’utilisateurs simplifie le déploiement dans l’ensemble de l’entreprise.

Comparaisons

La création de raccourcis de bureau manuellement ou par le biais de stratégies de groupe peut s’avérer fastidieuse et moins flexible que l’utilisation d’un script PowerShell. Les stratégies de groupe permettent une certaine automatisation, mais n’offrent pas le contrôle granulaire et la personnalisation qu’offre ce script. En outre, le script peut gérer des scénarios dynamiques tels que le téléchargement d’icônes à partir d’URL ou la conversion d’images encodées en base64, ce qui n’est pas possible avec les méthodes traditionnelles.

FAQ

  1. Ce script peut-il fonctionner sur toutes les versions de Windows ? Le script prend en charge Windows 7 et les versions plus récentes, y compris Windows Server 2008 et supérieur.
  2. Que se passe-t-il si le fichier d’icônes n’est pas valide ? Le script créera par défaut le raccourci sans icône si le fichier d’icône spécifié n’est pas valide.
  3. Comment le script gère-t-il les autorisations ? Le script vérifie la présence de privilèges élevés afin de s’assurer qu’il dispose des autorisations nécessaires pour créer des raccourcis dans plusieurs profils d’utilisateurs.
  4. Le script peut-il être modifié pour prendre en charge des paramètres supplémentaires ? Oui, le script est conçu pour être modulaire et peut être facilement étendu pour prendre en charge des paramètres ou des fonctionnalités supplémentaires.

Implications

L’automatisation de la création de raccourcis de bureau à l’aide de ce script PowerShell peut considérablement rationaliser les opérations informatiques, en réduisant les efforts manuels et en minimisant les risques d’erreurs. Cependant, il est essentiel de s’assurer que le script s’exécute avec les autorisations appropriées afin d’éviter les problèmes de sécurité. Une bonne gestion et distribution des raccourcis permet également de maintenir un environnement de bureau propre et organisé pour les utilisateurs.

Recommandations

Lors de l’utilisation de ce script :

  • Testez toujours dans un environnement contrôlé avant de le déployer auprès de tous les utilisateurs.
  • Veillez à ce que le répertoire d’icônes soit accessible à tous les utilisateurs ciblés.
  • Mettez régulièrement à jour le script pour gérer les nouveaux profils d’utilisateurs et l’évolution des besoins.
  • Conservez une documentation claire sur toutes les modifications apportées au script.

Conclusion

Les scripts PowerShell comme celui-ci sont des outils puissants pour les professionnels de l’informatique, car ils permettent d’automatiser et de personnaliser les tâches de routine. Pour les services informatiques et les MSP, l’utilisation de ces scripts peut conduire à des opérations plus efficaces et à une meilleure expérience pour l’utilisateur final.

NinjaOne, une plateforme complète de gestion informatique, peut intégrer de tels scripts dans ses flux d’automatisation, fournissant ainsi une solution transparente et puissante pour la gestion des environnements informatiques à grande échelle. En comprenant et en utilisant ce script PowerShell, les professionnels de l’informatique peuvent améliorer leur boîte à outils et assurer une gestion efficace des environnements de bureau.

Pour aller plus loin

Pour créer une équipe informatique efficace et performante, il est essentiel d'avoir une solution centralisée qui joue le rôle de nœud principal pour vos services. NinjaOne permet aux équipes informatiques de surveiller, gérer, sécuriser et prendre en charge tous les appareils, où qu'ils soient, sans avoir besoin d'une infrastructure complexe sur site. Pour en savoir plus sur NinjaOne Endpoint Management, participez à une visite guidée, ou profitez d'un essai gratuit de la plateforme NinjaOne.

Catégories :

Vous pourriez aussi aimer

×

Voir NinjaOne en action !

En soumettant ce formulaire, j'accepte la politique de confidentialité de NinjaOne.

Termes et conditions NinjaOne

En cliquant sur le bouton “J’accepte” ci-dessous, vous indiquez que vous acceptez les termes juridiques suivants ainsi que nos conditions d’utilisation:

  • Droits de propriété: NinjaOne possède et continuera de posséder tous les droits, titres et intérêts relatifs au script (y compris les droits d’auteur). NinjaOne vous accorde une licence limitée pour l’utilisation du script conformément à ces conditions légales.
  • Limitation de l’utilisation: Les scripts ne peuvent être utilisés qu’à des fins personnelles ou professionnelles internes légitimes et ne peuvent être partagés avec d’autres entités.
  • Interdiction de publication: Vous n’êtes en aucun cas autorisé à publier le script dans une bibliothèque de scripts appartenant à, ou sous le contrôle d’un autre fournisseur de logiciels.
  • Clause de non-responsabilité: Le texte est fourni “tel quel” et “tel que disponible”, sans garantie d’aucune sorte. NinjaOne ne promet ni ne garantit que le script sera exempt de défauts ou qu’il répondra à vos besoins ou attentes particulières.
  • Acceptation des risques: L’utilisation du script est sous votre propre responsabilité. Vous reconnaissez qu’il existe certains risques inhérents à l’utilisation du script, et vous comprenez et assumez chacun de ces risques.
  • Renonciation et exonération de responsabilité: Vous ne tiendrez pas NinjaOne pour responsable des conséquences négatives ou involontaires résultant de votre utilisation du script, et vous renoncez à tout droit ou recours légal ou équitable que vous pourriez avoir contre NinjaOne en rapport avec votre utilisation du script.
  • EULA: Si vous êtes un client de NinjaOne, votre utilisation du script est soumise au contrat de licence d’utilisateur final qui vous est applicable (End User License Agreement (EULA)).