2
votes

I've added a step to migrate our database to our dev server in Octopus Deploy. I trying to create a powershell script to do this. In the Nuget package for this deployment, my executable migrate.exe is in \Resources\.

I've written the script like this:

$dbServer = $OctopusParameters["DBServer"]
$dbUser = $OctopusParameters["DBUser"]
$dbPass = $OctopusParameters["DBPass"]

Write-Host ("Running migration " + $dbServer)

$CMD = ".\Resources\migrate.exe"
$arg1 = '--assembly "Database\bin\Debug\Database.dll" --provider sqlserver2014'
$arg2 = '--connection "data source=$dbServer;initial catalog=MyDB;user id=$dbUser;password=$dbPass;persist security info=true;MultipleActiveResultSets=True" -o'

& $CMD $arg1 $arg2

Write-host("Migration finished " + $dbServer)

But I get this message:

& : The term '.\Resources\migrate.exe --assembly "Database\bin\Debug\Database.dll" --provider sqlserver2014 --connection "data source=$dbServer;initial catalog=ClarkChains;user id=$dbUser;password=$dbPass;persist security info=true;MultipleActiveResultSets=True" -o' is not recognized as the name of a cmdlet, function, script file, or operable program.

I was looking around for examples on how to correctly call an executable.

2
Write-Host (Get-Location).Path - will tell you where you are in the octopus deployment target machine. - Alex M
it sounds like the .exe is included in the package. If that is the case, you can use the built-in octopus variables to retrieve the install path and set-location there. Also note, that you have powershell variable inside a single-quoted string, which is why your error message had $dbServer instead of the value. - Adam Bezverkov

2 Answers

3
votes

Adam's comment basically nails it.

Octopus has a lot of built-in variables, including a variable for the package directory of your current deployment. The documentation on system variables gives you the one you're looking for: Octopus.Tentacle.CurrentDeployment.PackageFilePath

And as Adam noted, if you want to use variables inside a string, you need to surround the string with double-quotes. PowerShell won't evaluate variables or expressions when you use single-quotes.

Also, since you're using double-quoted strings inside $arg1 and $arg2, you need to escape the double-quotes inside those strings with a backtick ` since they are needed to pass parameters to migrate.exe.

Your script should look something like this:

Set-Location $Octopus.Tentacle.CurrentDeployment.PackageFilePath

$dbServer = $OctopusParameters["DBServer"]
$dbUser = $OctopusParameters["DBUser"]
$dbPass = $OctopusParameters["DBPass"]

Write-Host ("Running migration $dbServer")

$CMD = ".\Resources\migrate.exe"
$arg1 = "--assembly `"Database\bin\Debug\Database.dll`" --provider sqlserver2014"
$arg2 = "--connection `"data source=$dbServer;initial catalog=MyDB;user id=$dbUser;password=$dbPass;persist security info=true;MultipleActiveResultSets=True`" -o"

& $CMD $arg1 $arg2

Write-host("Migration finished $dbServer")

(Sorry for not keeping the syntax highlighting, but all the escape characters messed with the syntax since it doesn't support syntax highlighting for PowerShell)

0
votes

The structure that you are using above is not incorrect but rather it looks like the environment is not structured correctly. Have a look at the following,

IF the migrate.exe file does not exist, you will receive the error that you have posted here.

& : The term '.\file.exe' is not recognized as the name of a cmdlet, ......

This indicates an environment issue and not a script issue. Ways you can resolve this include the following.

A> Define the full Path
B> Set a new location for the script.

E.g. If the 'file.exe' is in C:\temp\mytemp\file.exe then do the following in your script,

$CMD = 'C:\temp\mytemp\file.exe'

OR you can keep using your script as follows,

$CMD = '.\mytemp\file.exe'
Set-Location 'C:\temp\'

This way the file will be found. In summary you need to either change the location of your console script or set a full path to the file.
If you do not want to do either then I would recommend the following,

$myLocation = Get-Location
Set-Location 'C:\temp\'
& $CMD $arg1 $arg2
Set-Location $myLocation.Path

This way you are changing the location of the console to where you need it to be then returning to the location the console was set to in the first place.

Simply, please verify that the exe file exists in the target location.

Good Luck :)