How to execute powershell script from FAKE - F # MAKE

I am porting MSBuild code to FAKE - and I cannot execute powershell script from fake, below is the MSBuild file code written in FAKE:

<Target Name="VersionConfig"> 
    <Exec IgnoreExitCode="false" LogStandardErrorAsError="true" StandardErrorImportance="high" Command="powershell -File &quot;$(BuildRoot)\DeployScripts\scripts\AdminScripts\VersionUpdateFile.ps1&quot;  -path &quot;$(BuildSolutionVersioningConfig)&quot; -majorVersion &quot;$(BuildNumberMajor)&quot; -minor &quot;$(BuildNumberMinor)&quot; -build &quot;$(BuildNumber)&quot; -revision &quot;$(BuildNumberRevision)&quot;"/>
</Target>

      

How to write this in FAKE, I'm new to FAKE and haven't used F # much, so forgive me if it's obvious.

If anyone can help it would be really helpful.

Thank.

+3


source to share


2 answers


Fake.ProcessHelper

namespace
in FAKE is what you are looking for. The documentation will not tell you this, but is Fake.ProcessHelper

tagged with an attributeAutoOpen

, which means that all the functions listed in this API man page link are available to you from your FAKE script build without requiring any explicit instructions open

to use them. You use it like this:

let inQuotes s = sprintf "\"%s\"" s

Target "Sample" (fun _ ->
  let retCode =
    ExecProcess
      (fun info ->
        info.Name <- "powershell.exe"  // Don't know if you need full path here
        info.WorkingDirectory <- getBuildParam "BuildRoot"
        info.Arguments <-
          [ "-File"; getBuildParam "BuildRoot" + "\DeployScripts\scripts\AdminScripts\VersionUpdateFile.ps1" |> inQuotes;
            "-path"; getBuildParam "BuildSolutionVersioningConfig" |> inQuotes;
            "-majorVersion"; getBuildParam "BuildNumberMajor" |> inQuotes;
            "-minor"; getBuildParam "BuildNumberMinor" |> inQuotes;
            "-build"; getBuildParam "BuildNumber" |> inQuotes;
            "-revision"; getBuildParam "BuildNumberRevision" |> inQuotes
          ] |> separated " "
      )
      (TimeSpan.FromMinutes 5.0)
  if retCode <> 0 then
    failwith (sprintf "PowerShell exited with non-zero exit code %d" retCode)
)

      



A few notes:

+2


source


You can create a Powershell pipeline in any .NET application with the System.Management.Automation namespace classes . You can use this pipeline to execute commands locally or on a remote machine.

The next object gets a list of processes and prints them. This is the F # equivalent of the sample documentation for the PowerShell class:

Target "ProcTest" (fun _ ->
    PowerShell.Create()    
            .AddCommand("get-process")
            .Invoke()
            |> Seq.map(fun result->(  result.Properties.["ProcessName"].Value,
                                      result.Properties.["ID"].Value))
            |> Seq.iter (fun (name,id)->printfn "%-24O %O" name id)
)

      

This is a quick and dirty module that I use to execute commands (chocolate commands in particular) on a remote server. The only thing you need to get it to work on your local machine is to remove the parameter ComputerName

:

#r "System.Management.Automation"

module MyPowershell =

    let InvokeRemote server command =
        let block = ScriptBlock.Create(command)
        let pipe=PowerShell.Create()    
                .AddCommand("invoke-command")
        pipe.AddParameter("ComputerName", server)            
            .AddParameter("ScriptBlock", block)
            .Invoke() 
            |> Seq.map (sprintf  "%O")
            |> Seq.iter (fun line ->
                                let tracer=if line.Contains("not installed") then
                                                traceError 
                                        else 
                                                trace
                                tracer line)
        pipe.Streams.Error |> Seq.iter (traceError << sprintf "%O" )

      



The pipeline is represented by the PowerShell class . Steps to create it:

  • Create a PowerShell pipeline with PowerShell.Create ()
  • Create a ScriptBlock with the command you want to execute. For all commands, you don't need a ScriptBlock. In this case, ScriptBlock

    contains a script that I want to execute remotely.
  • Add what you want to accomplish. In my case, I want to run one commandinvoke-command

  • Add parameters. In this case, it is -ComputerName myServer

    , and -ScriptBlock ...

    with the executable unit.
  • Start the pipeline with PowerShell.Invoke ()
  • Parse the results for possible warning messages that didn't get caught in the error stream.

PowerShell errors are streamed Error

, making error handling easier.

Running the command on your local machine can be much easier:

let InvokeRemote command =
    let pipe=PowerShell.Create()    
            .AddCommand(command)
    pipe.Invoke() 
        |> Seq.map (sprintf  "%O")
        |> Seq.iter (fun line ->
                            let tracer=if line.Contains("not installed") then
                                            traceError 
                                    else 
                                            trace
                            tracer line)
    pipe.Streams.Error |> Seq.iter (traceError << sprintf "%O" )

      

+4


source







All Articles