Octopus Deploy not running PowerShell script - powershell

I have a Process Step in Octopus Deploy to run some Selenium WebDriver tests by calling a PowerShell script but it results in an error.
The PowerShell script is as follows:
set nunitPath="C:\AutomatedTests"
cd %nunitPath%\
nunit-console SiteCore.nunit /include:BulkyWasteTests
When the deployment takes place and the Process Step to run the script takes place, the following error occurs:
Set-Location : Cannot find path 'C:\Octopus\Work\20170110115049-7\%nunitPath%\' because it does not exist.
At C:\Octopus\Work\20170110115049-7\Script.ps1:2 char:3
+ cd %nunitPath%\
+ CategoryInfo : ObjectNotFound: (C:\Octopus\Work...-7\%nunitPath %\:String) [Set-Location], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.SetLocationCommand
The remote script failed with exit code 1
I don't understand why the error is reporting a different location to the location specified in the PowerShell script.
Any help greatly appreciated.

cd is an alias for Set-Location, so you can tell that it's the second line you need to change by looking at the error. Your cd line is trying to set the location to the %nunitpath% environment variable rather than the nunitPath script variable.
To reference the script variable use $nunitpath
So your script should look like:
set nunitPath "C:\AutomatedTests"
cd $nunitpath
nunit-console SiteCore.nunit /include:BulkyWasteTests
Edited with #4c74356b41 additional correct comment.

PowerShell doesn't use %variablename% syntax for expanding environment variable references in a string. That's cmd.exe syntax. In PowerShell, write $env:variablename instead.

Related

Running a PowerShell Script .PS1

I am trying to generate a MachineKey for my application using the PowerShell script found in kb2915218.
I have copied the function into notepad and saved as a .PS1 file. Now if I look at this file through explorer it is being recognised as a PowerShell file.
I then have run PowerShell and CD to the directory of my .PS1 file.
I then ran the following command:
Set-ExecutionPolicy Unrestricted
followed by:
.\Powershell-Generate-MachineKey.ps1
(the name of my script). And finally I then tried running the command
Generate-MachineKey
However I get the message:
Generate-MachineKey : The term 'Generate-MachineKey' is not recognized as the
name of a cmdlet, function, script file, or operable program. Check the spelling
of the name, or if a path was included, verify that the path is correct and try
again.
At line:1 char:1
+ Generate-MachineKey
+ ~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Generate-MachineKey:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Can someone please tell me where I am going wrong here?
The script just defines a function, so if you execute it like this:
.\Powershell-Generate-MachineKey.ps1
it won't do anything, because the function isn't invoked anywhere and also isn't made available in the current context. For the latter you need to dot-source the script
. .\Powershell-Generate-MachineKey.ps1
The dot-operator basically executes the script in the current context instead of a child context. That way the definitions from the script become available in the current context, and you can invoke the function like this:
Generate-MachineKey

jenkins cannot execute powershell under program files

I am using Jenkins for deployment. I wanted to run a powershell script that copies some files. I have installed "Windows Powershell" plugin for jenkins that will execute the powershell script. My Powershell script looks like below
param (
[string] $targetEnvironment,
[switch] $WhatIf,
[switch] $Compare)
try
{
#do smething here
}
catch
{
}
This script is working fine when i execute it manually. However when run the script using the following command in plugin's input window i get error
Note that, if i copied the "deploymentscript" folder to "C:\deploymentscript" and then change the path in plugin's window then the job runs fine.
It doesnt work when its executing under program files
The error im getting is
First time build. Skipping changelog.
[workspace] $ powershell.exe -NonInteractive -ExecutionPolicy ByPass "& 'C:\Users\CODESC~1\AppData\Local\Temp\hudson2119904511537985474.ps1'"
At C:\Users\username\AppData\Local\Temp\hudson2119904511537985474.ps1:1 char:119
+ ... etaTaskar.ps1' -targetEnvironment demo
+ ~~~~~~~~~~~~~~~~~~
Unexpected token '-targetEnvironment' in expression or statement.
At C:\Users\username\AppData\Local\Temp\hudson2119904511537985474.ps1:1 char:138
+ ... getEnvironment demo
+ ~~~~
Unexpected token 'demo' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParseException
+ FullyQualifiedErrorId : UnexpectedToken
Build step 'Windows PowerShell' marked build as failure
Finished: FAILURE
EDIT1
#petrik You are right, the space in the "Program Files (x86)" folder causing the issue. The solution is to use the following foormat
&("C:\Program Files (x86)\Jenkins\jobs\MyJob\workspace\crconfig\deploymentscript\Deploy.ps1") -targetEnvironment demo
and that works.
Now based on the article here if the powershell scrit fails i want the Jenkin's job to fail too,
So i have tell Hudson to call the powershell script form a windows batch task.
powershell "& {&('C:\Program Files (x86)\Jenkins\jobs\MyJob\workspace\crconfig\deploymentscript\Deploy.ps1') -targetEnvironment $Env:EnvironmentParam; exit $lastexitcode }"
I am not sure if i really need to this in my case ??
So in this case the problem is caused by the fact that the 'Program Files' path has spaces in it. Putting the path to the script into a variable which can then be executed using the call operator.
In order to ensure that Jenkins fails the build if the Powershell script fails several steps need to be taken.
Use the Jenkins powershell plugin. It will pass the powershell exit code on to Jenkins
Set the $ErrorActionPreference to 'Stop' as early as possible. This forces Powershell to halt when exceptions are thrown. The default behaviour is to report the error but then continue.
The script in the Jenkins configuration could look like this:
$ErrorActionPreference = 'Stop'
$scriptPath = 'c:\Program Files (x86)\Jenkins\jobs\MyJob\workspace\crconfig\deploymentscript\deploy.ps1'
& $script -targetEnvironment 'demo'
This should make Jenkins run the script correctly and report an error and stop the build if the script fails.
I did two things to resolve issue:
1) Appended the path to powerscript "c:\Users\\Documents\WindowsPowerShell\profile.ps1" to path variable of system properties.
2) Opened Powershell with administrative permissions and executed: "Set-ExecutionPolicy Unrestricted"
Then restarted windows machine. When i reconnected it to jenkins, my powershell just worked fine.

DPM Commands in Powershell Version 2

I am running a PowerShell script which requires connection to a DPM Server.
When I run run the Connect-DPMServer <DPM Server Name> cmdlet from the DPM Manangement Shell, the command succeeds and I am able to connect to the server.
However, when I enclose the same command in a script and invoke the script through the DPM Management Shell, the following error occurs:
The term 'Connect-DPMServer' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
+ CategoryInfo : ObjectNotFound: (Connect-DPMServer:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Similar is the case with other DPM cmdlets like Get-DPMProtectionGroup.
I am running Powershell version 2.0 on Windows Server 2008 R2.
What is the reason for this peculiar behaviour and how can I get around this?
Edit
There is some observation I made. My script has two parts: A wrapper script and a helper script which is called by the wrapper script as an independent job.
All the DPM Commands are identified in the wrapper script but they are not identified in the helper script when it runs as a job.
Any explanation why this may be and any suggestions to resolve the same?
I figured out the solution and here it is:
What is Happening
The wrapper script runs in the DPM PowerShell and then invokes a helper script as a separate job or thread. The environment in which this helper script runs is windows native powershell and not DPM Powershell. Hence the DPM commands are not identified there.
Solution
The DPM specific modules need to be imported as soon as the helper script is invoked. The steps are as follows :
Right Click on the DPM Management Shell icon and view properties.
Select the value of Target. For me, it looks like this C:\Windows\system32\windowspowershell\v1.0\powershell.exe -noexit -File "D:\DPM\DPM\bin\dpmcliinitscript.ps1"
The value of the parameter -File that is "D:\DPM\DPM\bin\dpmcliinitscript.ps1" is the file which when imported to Windows Powershell converts it to DPM Management Console. That means, it loads the shell with DPM commands.
Include this file in the helper script through dot-sourcing. Which means, the first line of the helper script should look like this : ."D:\DPM\DPM\bin\dpmcliinitscript.ps1"
This will help the invoked shell to identify the DPM specific commands.

PowerShell issue - I have to type ./ to run bat file

I've just installed PHP & Yii Framework. It works fine, I played with CMD. But after a while I switched to PowerShell ISE. I navigated to Yii folder:
cd C:\dev\yii-1.1.9.r3527\framework
and I issued command:
yiic.bat
and I get an error:
PS C:\dev\yii-1.1.9.r3527\framework> yiic.bat
The term 'yiic.bat' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:9
+ yiic.bat <<<<
+ CategoryInfo : ObjectNotFound: (yiic.bat:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
However when I type:
./yiic.bat
into PowerShell window, it works fine.
Is there a way to aviod typing ./ every time I run a bat file?
The framework directory you're trying to run the batch file from is evidently not in your path. When you type yiic.bat into the shell, it looks for that file in the list of directories contained in your path environment variable. See this question for information about how to set your path in powershell.
For example, if you want to be able to run batch files in the C:\dev\yii-1.1.9.r3527\framework directory, you can say $env:Path = $env:Path + ";C:\dev\yii-1.1.9.r3527\framework".
Or, as mloskot says, you can just add the current directory to your path, though that can pose a minor security risk. See e.g. this question for a bit of discussion on that.
this is an old question, but I stumbled on it looking for something else.
Powershell requires you to type .\ to run commands in the current by design.
https://blogs.technet.microsoft.com/csps/2010/06/06/introduction-to-windows-powershell-scripting/
I don't have PowerShell to try this out, but if you set the path to include current folder, this should work:
$env:Path = $env:Path + ";."

dot-source failing oin powergui

I'im trying to dot-source a script file in PowerGui 3.0 , but all i get is ;
The term '.\PowerShell.Common.ps1' is not recognized as the name of a
cmdlet, function, script file, or operable program. Check the spel
ling of the name, or if a path was included, verify that the path is
correct and try again. At
D:\TFS\SharePoint\Dev\Deploy\AutoSPInstaller\SP2010\AutoSPInstaller\AutoSPInstallerFunctionsCustom.ps1:6
char:31
+ .\PowerShell.Common.ps1 <<<<
+ CategoryInfo : ObjectNotFound:
(.\PowerShell.Common.ps1:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
And powerGui subsequently does not offer my script function within said file - in the context sensitive list in the parent script.
the file "PowerShell.Common.ps1" is in the same directory as AutoSPInstallerFunctionsCustom.ps1
Thank you for your assistance
To dot-source the file from PowerGUI's command line, make sure that your current working directory is at the script's directory. You can check this by typing $PWD at PowerGUI's command line.
To reference another script from a script you would do this:
# Get the current script's directory
$MyDir = Split-Path $MyInvocation.MyCommand.Definition
# Dot-source the external script by using the current script's directory
. "$MyDir\ScriptName.ps1"
Getting the script's directory ensures that even if your current working directory is not the same as the script's directory, you will be able to reference files relative to the script's location.
#Rynant is certainly correct in pointing out that the problem is you need to reference the script's directory rather than your current directory. However, it is important to note that his code solution is only partially correct; in fact, whether it works depends on where you call it!
A more robust solution is this:
function Get-ScriptDirectory
{
Split-Path $script:MyInvocation.MyCommand.Path
}
As it happens, I just wrote a detailed discussion analyzing this very point of correctly getting the script directory in another SO question. Rather than repeat my lengthy answer (complete with test vehicle and results matrix) I will provide this link.
This problem arises when you browse to the script you are working on from within PowerGUI.
Instead of changing the invocation paths to the other scripts you may prefer to run the script in-situ, i.e. with $PWD set to the directory of the script. This is most easily done by opening the script in PowerGUI through the Windows shell by using by the right-click context menu in Windows Explorer.