Monday, 23 September 2013

Running referenced powershell scripts from teamcity build.

I have been tasked  with creating automation for build process using PowerShell and TeamCity.

I have had multiple functions that I wanted to call in multiple steps, but the one issue had problem with was error:

[15:50:43][Step 7/8] .\ExecuteScripts.ps1 : The term '.\ExecuteScripts.ps1' is not recognized
[15:50:43][Step 7/8] as the name of a cmdlet, function, script file, or operable program. Check the
[15:50:43][Step 7/8] spelling of the name, or if a path was included, verify that the path is
[15:50:43][Step 7/8] correct and try again.
[15:50:43][Step 7/8] At \Path\RunUmbracoInstallation.ps1:5 char:1
[15:50:43][Step 7/8] + .\ExecuteScripts.ps1


This is so helpfull that I had to find way around it.
I have created basic file (test.ps1 - first version) that I have been able to execute from team build process.

After this step have been executing correctly though TeamCity.
I have set up permissions on powershell for user account under which teamcity agent run to FullControl.






File: test.ps1 - first version


 param(
        [Parameter(Mandatory=$True)] [string] $arg1,
        [Parameter(Mandatory=$True)] [string] $arg2
    )

function PowerShellTest{
  
    Write-Host -fore Magenta "Executing function powershell test with arguments:"
    Write-host -fore Cyan "arg1:$arg1  arg2:$arg2"
}

  
PowerShellTest


File: test.ps1 - final version

 param(
        [Parameter(Mandatory=$True)] [string] $arg1,
        [Parameter(Mandatory=$True)] [string] $arg2
    )


 <# ========== Loading required files ============ #>
$commons =Join-Path (Get-ScriptDirectory)"test2.ps1"
.$commons;

<# ========== Loading required files ============ #>

function PowerShellTest{
  

    Write-Host -fore Magenta "Executing function powershell test with arguments:"
    Write-host -fore Cyan "arg1:$arg1  arg2:$arg2"

    PowerShellTest2 -arg1 $arg1 -arg2 $arg2
}


function Get-ScriptDirectory
{
    $Invocation = (Get-Variable MyInvocation -Scope 1).Value
    Split-Path $Invocation.MyCommand.Path
}

  
PowerShellTest


File: test2.ps1



function PowerShellTest2{  

 param(
        [Parameter(Mandatory=$True)] [string] $arg1,
        [Parameter(Mandatory=$True)] [string] $arg2
    )

    Write-Host -fore Magenta "Executing function powershell test2:"
    Write-host -fore Cyan "arg1:$arg1  arg2:$arg2"
}



Now build configuration



Note:
  1. that script arguments do not have staring - before and value is in quotes.
  2. Powershell run mode: is defined as to what version of my PS and x64 is as my server version


After running agent again I do get results as:



 Execute PS Test script (Powershell)
[18:14:36][Step 8/8] Starting: Path\powershell.exe -NoProfile -NonInteractive -ExecutionPolicy ByPass -File PathToWorkDirectory\test.ps1 arg1="Test1" arg2="2Test2"
[18:14:36][Step 8/8] in directory: PathToWorkDirectory\
[18:14:37][Step 8/8] Executing function powershell test with arguments:
[18:14:37][Step 8/8] arg1:arg1=Test1 arg2:arg2=2Test2
[18:14:37][Step 8/8] Executing function powershell test2:
[18:14:37][Step 8/8] arg1:arg1=Test1 arg2:arg2=2Test2
[18:14:37][Step 8/8] Process exited with code 0


I have managed to do this thanks to this blog article.
http://leftlobed.wordpress.com/2008/06/04/getting-the-current-script-directory-in-powershell/