Powershell parameter passing to function - function

I'm facing with an annoying problem: my script seemingly doesn't pass any argument to a function I've defined.
$server = 'http://127.0.0.1:8080'
Function Get-WorkingDirectory([string]$address)
{
#echo $address
$content = Get-Content -path C:\....\file.txt
$content -contains $address
} #end Get-WorkingDirectory function
if(Get-WorkingDirectory $server)
{
echo "works"
}
else
{
echo "error"
}
It is stuck on "works". If I try to echo address in the function, it is empty.
What the heck I'm doing wrong?! I know this is a pretty noobish question, but I tried everything I found on the net.
Thanks in advance for help!

echo is an alias for Write-Output but as you are using the output of the function in the if statement, nothing gets shown.
For testing purposes, use Write-Host in this instance to show the variable being passed correctly.
$server = 'http://127.0.0.1:8080'
Function Get-WorkingDirectory([string]$address)
{
write-host "$address using write host"
} #end Get-WorkingDirectory function
if (Get-WorkingDirectory $server) {
}

Output of Get-WorkingDirectory is shadowed by if statement.
Try to use it without if and you'll see that argument is passed correctly. For example,
$server = 'http://127.0.0.1:8080'
Function Get-WorkingDirectory([string]$address)
{
Write-Host $address
}
Get-WorkingDirectory $server
Address is printed well

Related

How to handle the result of a Powershell Object to call a function

Here is my code:
function setParameterb () {
$Name = $args[0]
"Arg1: $Name"
}
Write-Output "### Starte AlertlogRotate ###"
$folders = #('d:', 'e:', 'f:', 'g:', 'h:', 'i:', 'j:', 'k:', 'l:')
foreach ($i in $folders) {
$filenames = Get-ChildItem -Path $i\*\log -ErrorAction SilentlyContinue -Recurse -Filter alert_*.log | Select-Object FullName
}
The setParametersb function is just for test now and should only print the result. Later, I will use it to zip logfiles which get too big.
I need to get the result of this powershell object into a string to call a function for every line.
The Object looks like this:
FullName
--------
D:\AREA\log\diag\rdbms\area\area\trace\alert_area.log
D:\CONS\log\diag\rdbms\cons\cons\trace\alert_cons.log
D:\DEV01\log\diag\rdbms\dev01\dev01\trace\alert_dev01.log
G:\TEST01\LOG\diag\rdbms\test01\test01\trace\alert_test01.log
G:\TEST02\log\diag\rdbms\test02\test02\trace\alert_test02.log
I know, that I have to crop the headline "FullName", the row"--------" and some empty lines, but this is not my problem now.
My problem is to transfer the object $filenames into an array to be able to call the function setParameterb with every single line from the output.
tried lots of other stuff, but finally this solved my problem:
$filenames |ForEach-Object { setParameterb $_.FullName }
try stuff like
function setParameterb () {
param (
[Parameter(Mandatory=$true)]
$names,
)
foreach($name in $names){
"Arg1: $name"
}
}

Powershell - Store function output in variable not working

stuck at this one trying to store function output in a variable:
function AD-prompt($Text)
{
do
{
$in = read-host -prompt "$Text"
}
while($in -eq "")
}
calling the function with
$type = AD-prompt "Sample Text"
does not store anything in $type - only when i remove the entire do-while loop it works. it seems the function output is empty as the read-host output is stored in the $in variable, but i have no idea how to solve this - i didnt find another way to loop the read-host aswell sadly.
You need to return $in from your function by outputting it. You can do this by putting it on a line on its own after your loop:
function AD-prompt($Text)
{
do
{
$in = read-host -prompt "$Text"
}
while($in -eq "")
$in
}

PowerShell adds other values to return value of function

It seems that PowerShell adds an additional variable to the return value of a function.
The function subfoo2 itself delivers the correct values, but as soon as PowerShell jumps back to the postion where I called the function (in foo1), value contains the value of an other variable ($msg)
(Have a look at the comments in the code)
writeMessageLog($msg){
...
Add-Content $msg
...
}
subfoo2{
writeMessageLog($msg)
return $UserArrayWithValues #During Debug, $Array is fine (1)
}
foo1{
$var = subfoo2 $UserArray # $var has now the value of $msg and $UserArrayWithValues (2)
#do something with var
}
Realcode:
function WriteLog
{
param ( [string] $severity , $msgNumber, [string] $msg )
...
$msgOut = $date + ... + $msg
Add-Content $msgout ( $msgOut )
...
}
function getFeatures
{
writelog 'I' 1002 $true $true "Load Features"
$Features = importCsv -pPath $FeatureDefintionFilePath
Writelog 'I' 1000 $true $true "Features Loaded"
return $Features # $Features has value as expected (1)
}
function GetUserFeatures ($pUserObject)
{
$SfBFeatures = ""
$SfBFeatures = getFeatures #SfBFeaures has Value of $msg and $Features (2)
...
}
Do I use the functions/return values wrong? What could lead to such behavior? Is it an issue if i call a function within a function?
If I remove $msgOut = $date + ... + $msg in writeMessageLog, the values are fine.
I'm pretty lost right now, and have no ideas where this comes from. Any ideas welcome.
This is how powershell works, basically everything that you print out will be returned as the function output. So don't output extra stuff. To force something to not output stuff you can do:
$null = some-command_that_outputs_unwanted_things
since everybody is obsessed with Out-Null I'll add this link showing several other ways to do that.
Within a function, everything you don't assign or pipe to a consuming cmdlet will get put to the pipeline and returned from the function - even if you don't explicit return it. In fact the return keyword doesn't do anything in PowerShell so the following is equivalent:
function Test-Func
{
"Hello World"
}
function Test-Func
{
return "Hello World"
}
So it looks like your writeMessageLog puts anything on the pipeline thus you have to either assign the value to anything:
$notUsed = writeMessageLog($msg)
or (prefered) pipe it to the Out-Null cmdlet:
writeMessageLog($msg) | Out-Null

PowerShell function return type not as expected

I have a script that accepts a string parameter :
script-that-takes-string-param.ps1
param(
[Parameter(Mandatory=$true, HelpMessage="path")]
[string]$path,
)
And I have another script that calls the first script :
parent-script.ps1
function CreateDir($dir) {
if (!(Test-Path $dir)) {
mkdir $dir
}
}
function CreatePath($BaseDir, $Environment, $Site, $Domain){
$path = [string]::format("{0}{1}\{2}\{3}", $BaseDir, $Environment, $Site, $Domain)
CreateDir $path
$path
}
$path = CreatePath 'c:\web\' 'qa' 'site1' 'com'
.\script-that-takes-string-param.ps1 -path $path
Running this script throws the exception :
"Cannot process argument transformation on parameter 'path'. Cannot convert value to type System.String"
Casting the parameter doesn't work :
.\script-that-takes-string-param.ps1 -path [string] $path
And casting the function result doesn't work either :
$path = [string] CreatePath 'global' 'site1'
But what is really strange is that if I run parent-script.ps1 twice from the PS command line, the 1st time it throws exceptions, but the 2nd time it executes with no errors.
My best guess would be that your
#do some other stuff with $path
writes something to the standard output, causing the function to return an array that contains said output and the path you expect. Can you send details on what you do in that bit?
Try removing "return". Output that is not saved to a variable is automatically returned. It shouldn't do any difference but it won't hurt to try.
Can you provide a full exception? Without seing the complete exception I get the feeling that the error is caused by something inside your script(ex. a function).
EDIT Your mkdir is causing the problem. When you run it, it returns an object representing the created directory(a DirectoryInfo object if I remember correctly). To fix this, try:
function CreateDir($dir) {
if (!(Test-Path $dir)) {
mkdir $dir | out-null
}
}
or combine them like:
function CreatePath($BaseDir, $Environment, $Site, $Domain){
$path = [string]::format("{0}{1}\{2}\{3}", $BaseDir, $Environment, $Site, $Domain)
if(!(Test-Path $path -PathType Container)) {
New-Item $path -ItemType Directory | Out-Null
}
$path
}

Create a function with optional call variables

Is there a way to create a parameter in a PowerShell function where you have to call it in order to have it considered?
An example given by commandlet (the bold being what I want to do):
Invoke-Command -computername Server01 -Scriptblock {...}
Here is an example of what I want to do with the function
Function DoStuff($computername, -arg2, -domain $domain)
Test-parameter(-domain) if (-domain -eq $true) {
use $domain
}
Else {
$domain = "Domain1"
}
test-parameter($arg2) {
if ($arg2 -eq $true) {
Do something
}
else {
Do the opposite
}
}
So in summary:
If "-arg2" is present, I want something to happen in the script. If "-Domain" is present and has an argument with it, I want that to be used rather then the set argument.
Powershell provides a lot of built-in support for common parameter scenarios, including mandatory parameters, optional parameters, "switch" (aka flag) parameters, and "parameter sets."
By default, all parameters are optional. The most basic approach is to simply check each one for $null, then implement whatever logic you want from there. This is basically what you have already shown in your sample code.
If you want to learn about all of the special support that Powershell can give you, check out these links:
about_Functions
about_Functions_Advanced
about_Functions_Advanced_Parameters
I don't think your question is very clear, this code assumes that if you're going to include the -domain parameter, it's always 'named' (i.e. dostuff computername arg2 -domain domain); this also makes the computername parameter mandatory.
Function DoStuff(){
param(
[Parameter(Mandatory=$true)][string]$computername,
[Parameter(Mandatory=$false)][string]$arg2,
[Parameter(Mandatory=$false)][string]$domain
)
if(!($domain)){
$domain = 'domain1'
}
write-host $domain
if($arg2){
write-host "arg2 present... executing script block"
}
else{
write-host "arg2 missing... exiting or whatever"
}
}
Not sure I understand the question correctly.
From what I gather, you want to be able to assign a value to Domain if it is null and also what to check if $args2 is supplied and according to the value, execute a certain code?
I changed the code to reassemble the assumptions made above.
Function DoStuff($computername, $arg2, $domain)
{
if($domain -ne $null)
{
$domain = "Domain1"
}
if($arg2 -eq $null)
{
}
else
{
}
}
DoStuff -computername "Test" -arg2 "" -domain "Domain2"
DoStuff -computername "Test" -arg2 "Test" -domain ""
DoStuff -computername "Test" -domain "Domain2"
DoStuff -computername "Test" -arg2 "Domain2"
Did that help?