I have a powershell script called PostPro.ps1.I would like to provide a hookups to this script so
that if there is need one can add functionality before and after execution of PostPro.ps1 script.
Thanks in advance for your help!
Ramani
another way with parameters :
postpro.ps1:
[CmdletBinding()]
Param(
[ScriptBlock]$before,
[ScriptBlock]$after
)
if($before -ne $null){
Invoke-Command $before
}
write-host "hello"
if($after -ne $null){
Invoke-Command $after
}
then one can provide script to execute :
$b={write-host "before"}
$a={write-host 'after' }
PS>.\postpro.ps1 -before $b -after $a
before
hello
after
One way to do this would be to use modules. If you put all of your extension functions in modules in a certain folder with a certain name format, and then each module needs a runBefore and a runAfter function.
In your PostPro.ps1 script you can load the modules like this:
$modules = ls $(Join-Path $hookDir "postPro-extension-*.psm1") |
% { import-Module $_.FullName -AsCustomObject }
This will load all of the files in $hookDir that have a name that looks like postPro-extension-doSomething.psm1. Each module will be stored in a object that will give you access to each modules functions. To run the functions you can just call them on each object as show below.
You can go like this before the main part of the script
$modules | % { $_.runBefore }
and this after the main part of the script
$module | % { $_.runAfter }
Related
Is there a simple way to add a bash function to the environment provided by stdenv? When developing with 'nix-shell', I can run commands like 'unpackPhase' or 'buildPhase' because mkDerivation puts them in scope--its super useful. My derivation attributes are added to the environment as well. But I'd also like to see a way to automatically add an attribute as a function in the build/shell environment.
To explain what I'm getting at, I can currently get functions into the environment by either using eval statements or toFile and source. For instance, with eval, something like:
{ stdenv, ... } : stdenv.mkDerivation
{ shellHook = ''eval "$myFunctions"'';
myFunctions = ''
myFunction1(){
echo "doing myFunction1"
}
myFunction2(){
echo "doing myFunction2"
}
''
}
will "source" myFunction1 and myFunction2 when I enter the nix-shell.
However, I was expecting something like a mkFunction utility to compliment mkWrapper, mkProgram, and other such basic utilities. I'd expect to use it like in the below, where the the attributes defined using mkFunction are automatically "sourced" as above.
{ stdenv, mkFunction, ... } : stdenv.mkDerivation
{ myFunction1 = mkFunction '' echo "doing myFunction1" '';
myFunction2 = mkFunction '' echo "doing myFunction2" '';
shellHook = '' echo "No need to source, myFunctions are already in scope." '';
}
I think such a utility would be useful. I thought setup hooks might cover this use, but I'm not really sure how to use them. And its not so bad doing it the first way (If I hadn't figured it out during the course of writing the question I wouldn't have bothered asking). But it seems like the kind of utility that nix would already have available, so I'm asking anyway.
Setup hooks can indeed do that, here's a simple example of one that defines a function foo:
with import <nixpkgs> {};
let
fooHook = stdenv.mkDerivation {
name = "foo-hook";
# Setting phases directly is usually discouraged, but in this case we really
# only need fixupPhase because that's what installs setup hooks
phases = [ "fixupPhase" ];
setupHook = writeText "my-setup-hook" ''
foo() { echo "Foo was called!"; }
'';
};
in mkShell {
buildInputs = [ fooHook ];
shellHook = "foo";
}
Running nix-shell on this yields the desired result:
$ nix-shell
Foo was called!
[nix-shell:~]$
Another simple possibility is to use the runHook function provided by stdenv.
with import <nixpkgs> {};
mkShell rec {
name = "runs-hook";
myFun = "echo The name is ${name}";
}
In the snippet above, a variable myFun is made available in the shell/build environment. You call it with:
> runHook myFun
The name is runs-hook
This is really similar to the eval method from the question.
I'd like to configure a choice parameter in Jenkins.
The parameter I'd like to configure is called CIDR.
I tried using "Extended choice parameter" plugin but to no avail.
What I'm trying to do, is to let the user manually insert the chosen CIDR, considering the CIDRs which are already in use -> I want to run a groovy script to populate the string description with CIDRs which are already in use.
In order to list the already in use CIDRs, I wrote the following Groovy code:
#!/usr/local/bin/groovy
def p = ['/usr/local/bin/aws', 'ec2', 'describe-vpcs'].execute() | 'grep CidrBlock'.execute() | ['awk', '{print $2}'].execute() | ['tr', '-d', '"\\"\\|,"'].execute()
p.waitFor()
println p.text
The script runs properly in terminal:
itai#Itais-MacBook-Pro ~ - $ groovy cidrs.groovy
172.31.0.0/16
172.51.0.0/16
172.51.0.0/16
I even accepted a suspicious signature in Jenkins in-script approvals to allow the script to run.
But when I insert it to the Groovy script section of the string description and run the "build the job with parameters", the string dropdown stays empty.
What am I doing wrong?
Looks trivial issue. Try below.
Change From :
println p.text
To:
return p.text
The reason why the parameter kept being empty is that as it seems, the "Extended Choice Parameter" plugin expects the output to be an array.
Changing the script to the following code solved the issue:
#!/opt/groovy-2.4.12/bin/groovy
def p = ['/usr/bin/aws', 'ec2', 'describe-vpcs'].execute() | 'grep CidrBlock'.execute() | ['awk', '{print $2}'].execute() | ['tr', '-d', '"\\"\\|,"'].execute()
p.waitFor()
def output = []
p.text.eachLine { line ->
output << line
}
output.each {
println it
}
Now the parameter is populated with the available CIDRs.
In a PowerShell workflow, the following is valid:
$strings='one','two','three'
foreach -parallel($string in $strings)
{
"Hello: $string"
}
A shorhand way of writing this (without the parallel piece) would be:
$strings='one','two','three'
$strings | `
%{
"Hello: $_"
}
Is there a way to use the shorthand version, specifying that it should be run in parallel?
Not that I can see.
% is a default alias for ForEach-Object which is a core cmdlet. foreach -parallel within workflows is a workflow activity that is separate form the cmdlet and only callable within workflows. In this case, you would need to set an alias to foreach -parallel in your workflow to call the workflow activity - but manipulating aliases is disallowed within workflows (source).
For a script that should be compatible to powerShell 2, I have a param called $exeLoc, declared as follows:
Param(
[parameter()]
[alias("el")]
$exeLoc= '......\sw' )
I try to set that parameter, from relative to absolute in a function, as follows:
Function FromRelToAbs()
{
Push-Location $exeLoc
$Global:exeLoc = (Join-path $PWD -ChildPath '\Vis.exe' )
Pop-Location
}
However, after calling the function above, the value of $exeLoc does not change.
The above code works perfectly on powersell v3 AND in powershell v2 ISE. It does not work properly on a powershell v2 window ( not ISE )
Any ideas ?
I take it your script is something along these lines:
param($x = 2)
write-output "[script] Value of x is 2"
function blah {
$global:x = 5
write-output "[blah] Setting x as 5"
}
Write-Output "Calling function blah"
blah
Write-Output "[script] Value of x is $x"
You set the variable in the script; and within the script is a function that refers to the variable in the global scope and sets its value.
If I try the above on my machine (PowerShell v2) it does set the variable correctly. Maybe I understood your script wrong?
I use powershell to invoke a sql stored procedure, now I want to redirect the complete set of the output into a .ps1 file, because the the output line is executable in powershell.
I'm trying to use >output.ps1, it works, but I'm checking the output file, it contains a lot of '...' to replace real output.
How to export the complete output? also stripe the header off?
Thanks.
It depends how you invoke the stored procedure. If you're invoking it within PowerShell, you should be able to collect the output, so I assume you're starting it as a separate task its own window. Without your actual example, here's a way to collect the output from the tasklist.exe command. You may find it applicable.
cls
$exe = 'c:\Windows\System32\tasklist.exe'
$processArgs = '/NH'
try {
Write-Host ("Launching '$exe $processArgs'")
$info = New-Object System.Diagnostics.ProcessStartInfo
$info.UseShellExecute = $false
$info.RedirectStandardError = $true
$info.RedirectStandardOutput = $true
$info.RedirectStandardInput = $true
$info.WindowStyle = [System.Diagnostics.ProcessWindowStyle]::Hidden
$info.CreateNoWindow = $true
$info.ErrorDialog = $false
$info.WorkingDirectory = $workingDir
$info.Filename = $exe
$info.Arguments = $processArgs
$process = [System.Diagnostics.Process]::Start($info)
Write-Host ("Launched $($process.Id) at $(Get-Date)")
<#
$process.StandardOutput.ReadToEnd() is a synchronous read. You cannot sync read both output and error streams.
$process.BeginOutputReadLine() is an async read. You can do as many of these as you'd like.
Either way, you must finish reading before calling $process.WaitForExit()
http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.redirectstandardoutput.aspx
#>
$output = $process.StandardOutput.ReadToEnd()
$process.WaitForExit() | Out-Null
Write-Host ("Exited at $(Get-Date)`n$output")
} catch {
Write-Host ("Failed to launch '$exe $processArgs'")
Write-Host ("Failure due to $_")
}
$output