File System - Create Symlink

Octopus.Script exported 2014-08-26 by diegoavanzini belongs to ‘File System’ category.

Creates a Symbolic Link

Parameters

When steps based on the template are included in a project’s deployment process, the parameters below can be set.

LinkPath

link_path

null

TargetPath

target_path

null

Script body

Steps based on this template will execute the following PowerShell script.

function New-Symlink {
    <#
    .SYNOPSIS
        Creates a symbolic link.
    #>
    param (
        [Parameter(Position=0, Mandatory=$true)]
        [string] $Link,
        [Parameter(Position=1, Mandatory=$true)]
        [string] $Target
    )

    Write-Host "New-Symlink $Link to $Target"
    
    Invoke-MKLINK -Link $Link -Target $Target
}

function Invoke-MKLINK {
    <#
    .SYNOPSIS
        Creates a symbolic link.
    #>
    param (
        [Parameter(Position=0, Mandatory=$true)]
        [string] $Link,
        [Parameter(Position=1, Mandatory=$true)]
        [string] $Target
    )
    
    # Resolve the paths incase a relative path was passed in.
    $Link = (Force-Resolve-Path $Link)
    $Target = (Force-Resolve-Path $Target)

    # Ensure target exists.
    if (-not(Test-Path $Target)) {
        throw "Target does not exist.`nTarget: $Target"
    }

    # Ensure link does not exist.
    if (Test-Path $Link) {
        Write-Host "A file or directory already exists at the link path.`nLink: $Link"
        return
    }

    $isDirectory = (Get-Item $Target).PSIsContainer

    # Capture the MKLINK output so we can return it properly.
    # Includes a redirect of STDERR to STDOUT so we can capture it as well.
    $output = cmd /c mklink /D `"$Link`" `"$Target`" 2>&1
    
    Write-Host "output : $output"
    if ($lastExitCode -ne 0) {
        Write-Host "MKLINK failed. Exit code: $lastExitCode`n$output"
        throw "MKLINK failed. Exit code: $lastExitCode`n$output"
    }
    else {
        Write-Output $output
    }
}

function Force-Resolve-Path {
    <#
    .SYNOPSIS
        Calls Resolve-Path but works for files that don't exist.
    .REMARKS
        From http://devhawk.net/2010/01/21/fixing-powershells-busted-resolve-path-cmdlet/
    #>
    param (
        [string] $FileName
    )
    
    $FileName = Resolve-Path $FileName -ErrorAction SilentlyContinue `
                                       -ErrorVariable _frperror
    if (-not($FileName)) {
        $FileName = $_frperror[0].TargetObject
    }
    
    return $FileName
}

New-Symlink $link_path $target_path



Provided under the Apache License version 2.0.

Report an issue

To use this template in Octopus Deploy, copy the JSON below and paste it into the Library → Step templates → Import dialog.

{
  "Id": "f0cae939-caef-4979-93ac-6c9b3a3c4986",
  "Name": "File System - Create Symlink",
  "Description": "Creates a Symbolic Link",
  "Version": 23,
  "ExportedAt": "2014-08-26T15:58:34.242+00:00",
  "ActionType": "Octopus.Script",
  "Author": "diegoavanzini",
  "Parameters": [
    {
      "Name": "link_path",
      "Label": "LinkPath",
      "HelpText": null,
      "DefaultValue": null,
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Name": "target_path",
      "Label": "TargetPath",
      "HelpText": null,
      "DefaultValue": null,
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    }
  ],
  "Properties": {
    "Octopus.Action.Script.ScriptBody": "function New-Symlink {\n    <#\n    .SYNOPSIS\n        Creates a symbolic link.\n    #>\n    param (\n        [Parameter(Position=0, Mandatory=$true)]\n        [string] $Link,\n        [Parameter(Position=1, Mandatory=$true)]\n        [string] $Target\n    )\n\n    Write-Host \"New-Symlink $Link to $Target\"\n    \n    Invoke-MKLINK -Link $Link -Target $Target\n}\n\nfunction Invoke-MKLINK {\n    <#\n    .SYNOPSIS\n        Creates a symbolic link.\n    #>\n    param (\n        [Parameter(Position=0, Mandatory=$true)]\n        [string] $Link,\n        [Parameter(Position=1, Mandatory=$true)]\n        [string] $Target\n    )\n    \n    # Resolve the paths incase a relative path was passed in.\n    $Link = (Force-Resolve-Path $Link)\n    $Target = (Force-Resolve-Path $Target)\n\n    # Ensure target exists.\n    if (-not(Test-Path $Target)) {\n        throw \"Target does not exist.`nTarget: $Target\"\n    }\n\n    # Ensure link does not exist.\n    if (Test-Path $Link) {\n        Write-Host \"A file or directory already exists at the link path.`nLink: $Link\"\n        return\n    }\n\n    $isDirectory = (Get-Item $Target).PSIsContainer\n\n    # Capture the MKLINK output so we can return it properly.\n    # Includes a redirect of STDERR to STDOUT so we can capture it as well.\n    $output = cmd /c mklink /D `\"$Link`\" `\"$Target`\" 2>&1\n    \n    Write-Host \"output : $output\"\n    if ($lastExitCode -ne 0) {\n        Write-Host \"MKLINK failed. Exit code: $lastExitCode`n$output\"\n        throw \"MKLINK failed. Exit code: $lastExitCode`n$output\"\n    }\n    else {\n        Write-Output $output\n    }\n}\n\nfunction Force-Resolve-Path {\n    <#\n    .SYNOPSIS\n        Calls Resolve-Path but works for files that don't exist.\n    .REMARKS\n        From http://devhawk.net/2010/01/21/fixing-powershells-busted-resolve-path-cmdlet/\n    #>\n    param (\n        [string] $FileName\n    )\n    \n    $FileName = Resolve-Path $FileName -ErrorAction SilentlyContinue `\n                                       -ErrorVariable _frperror\n    if (-not($FileName)) {\n        $FileName = $_frperror[0].TargetObject\n    }\n    \n    return $FileName\n}\n\nNew-Symlink $link_path $target_path\n\n\n",
    "Octopus.Action.Script.Syntax": "PowerShell"
  },
  "Category": "File System",
  "HistoryUrl": "https://github.com/OctopusDeploy/Library/commits/master/step-templates//opt/buildagent/work/75443764cd38076d/step-templates/file-system-create-symlink.json",
  "Website": "/step-templates/f0cae939-caef-4979-93ac-6c9b3a3c4986",
  "Logo": "iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAMAAACahl6sAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAKhQTFRF/////78A/6oAVVVV/++//+q/gICA1dXV/79A/9R///ff/8MQ/9dg/8cg//vv/68A/+ef//PP//rv/7Ug/68Q/+Sv/8sw/9tw/9NQ/89w/+uv/+OP/8pg/89A/8VQ/9+f/9+A/9qP/+/P/99//7cA/7IA/7wA/6sA/+/A39/f/64A2tjX//Tfn5+f/7MA/7sA/74A/60A/9Zw/7gA/74Q/7oA/7UA/7EAi6g4fwAAAuRJREFUeNrs21tT2mAUheEvaaCQQCSczyi29WzP7f//Z6UdZBIIM44us9hf13vbC+eRbLo3qnNKKaWUUkoppZRSSimllFJKKaWUwlVrLhsvbrLqnoai2+yFr2x+fwKOwasZm/oXdEczxDQnOyYhqgn3uQpxDZhz3gdCesQ3r3mIjDfwXagj7NEgKywkXLMgSzCE9mz1wBDaOzDYETYEEUSQ/wPSaz6rQa174pDnt1x5Atm8emtPIGG48gUClJAh/XtPILi36+L3Zz6oVdBF4w32/sIbYmWH6qAPX5fzjio/14Q/W7nnqtIPDnYfFfThkGpPovXu68IhNdKSVyXkoQ7qgQypvwNVFwQDuXkP6oYM8WbYBWFDYMPNHnZBTv3tV8MuiCC+Q6K36+ypkn/LsJC4lQSkhhkQch4Qa+MgrYBahIKcB35AYrIjyEAQ9gsCm5E2GTIDQabsJysFQcZkxxj0H2LKfkGmIMjM3KgfgbBHfQSCROwnKwZByNtJsACt8WlChnRAkA7ZkaAOqyEZ0gJB7O2LRyAjsmOIutlNjnoJhD3qL9gXyyFjk6N+CKGPegSC2DsNj0DY++IlCEI/DWMQhL0vjh0GYvE0LIWwT8PEgSDsfXEEgmRmR30PYvI0LIGkRvfFAwj9NExBkIXRfXEfYvQ0PISwT8O2A0HYoz4DQb4ZPQ0PID8sj3oO8tXuvliEPJoe9Rzkk9XTcA9yZnhfLEA+mD0Ni5Ar9gvSAUE+2j0Ni5DPdk/DAuTW9L6Yg7BHfehAkC/WR30LoY96CoL8tL0v7iD0fTECQX4Z3xd3EPa+OANBflvfF58g363vi1sIfV+cgiCPPoz6Xwh71EcgyK0Xo76BsPfFBcbhrjzYF/9l/zTcxj4NWyBH7Mmo038zFvWCsCHt1HnxaCWZg8X8ifQwxjlcSvsJaHLpsGW5v2S8vo4qyymF7+5O3wOllFJKKaWUUkoppZRSSimllPKxPwIMAPj2YtijZbi5AAAAAElFTkSuQmCC",
  "$Meta": {
    "Type": "ActionTemplate"
  }
}

History

Page updated on Tuesday, August 26, 2014