This question already has answers here:
powershell contains not working
(5 answers)
Closed 5 years ago.
I'm trying to create a powershell script that has an if statement depending on what a variable starts with basically.
I have this code:
if($content -contains "fail*") {
#Not all ID's exist/could not be created. pop up error code :(
"match"
} else {
#At this point, we should have a list of hardware id's identifier from our database.
"no match"
}
The powershell $_POST's data to my server, for a response. If that response starts with fail it should go down the first branch, if it returns anything else, it should go down the other branch.
My PHP code can only return 1 result right now, as I was testing this. This is my php code:
<?
include("db-connector.php");
echo "fail - ".$_POST['device'];
?>
The included file contains no output. As you can see, the result should ALWAYS go down the fail branch, but it actually doesn't. Why am I getting this result?
Consider using -like if you're using a wildcard to compare to.
about_Comparison_Operators
Related
i'm currently trying to do a small script to retrieve data from a server using REST endpoint. As it's the first time i work with powershell, i'm a bit disappointed by the 'lack' of structure and 'typing' in it.
Then i structured my code like this with comments :
# declare ------------------------------------------------------------------------------------------
// All the var i'll need in my process
# do -----------------------------------------------------------------------------------------------
// Ask for user to enter URL and credentials
// Check if credentials are correct
// Connect to the server
// Retrieves the data in a list (JSON formatted) --> List REST EndPoint
// Foreach document in my list
// retrieve the document's details --> single file REST EndPoint
// download the file into local directory
// End Foreach
# display results ----------------------------------------------------------------------------------
// display :
// Downloaded files
// Non-Downloaded files
During review, my colleague told me "Oh ! What you need is the 'begin-process-end' " and then just leave.
I then read somethings about this here but for what i see, the structure is the same as i did with my comments but i don't see the point where it's "What i need" as a functionalities.
Since i'm a real beginner, i maybe miss the point. Could you explain it to me ?
(btw, thx to the kind person who'll edit my ugly english mistakes)
Think of these blocks as a pre-processor (the begin block), actual processor (the process block), and a post-processor(the end block) to a function.
You don't need to define any of these blocks (although Begin and End block will always need a Process block), and can write code just fine without them, but the idea behind them is to divide the function into three separate areas of code. The following function should make it a little clearer:
function addition_by_one {
# Arguments to a powershell functions are defined inside the param block.
Param (
[int]$number
)
# In the below begin block, the variable $a was initialized to 1.
Begin {
$a = 1
}
# The Process block does the main work. In this case, $a is added to the argument supplied to the function.
Process {
$sum = $number + $a
}
# Finally, the End block will execute after the process block completes.
End {
"Sum is $sum"
}
}
# Call the function with any integer argument.
addition_by_one -number 3
Being/process/end is really for pipelines. You can't process from the pipe without a process block.
1..5 | & { process {$_ * 2} }
2
4
6
8
10
I'm using a function that I call from another script. It prompts a user for input until it gets back something that is not empty or null.
function GetUserInputValue($InputValue)
{
do{
$UserValue = Read-Host -Prompt $InputValue
if (!$UserValue) { $InputValue + ' cannot be empty' }
}while(!$UserValue)
$UserValue
return $UserValue
}
The issue is quite strange and likely a result of my lack of powershell experience. When I run the code and provide empty results, the messages from the if statement queue up and only display when I finally provide a valid input. See my console output below.
Console Results
test:
test:
test:
test:
test:
test:
test: 1
test cannot be empty
test cannot be empty
test cannot be empty
test cannot be empty
test cannot be empty
test cannot be empty
1
I can make this work however in the main file with hard coded values.
do{
$Server = Read-Host -Prompt 'Server'
if (!$Server) { 'Server cannot be empty' }
}while(!$Server)
I'm working Visual Studio Code. This is a function I have in another file I've named functions.ps1.
I call this from my main file like this,
$test = GetUserInputValue("test")
$test
When you put a naked value in a script like "here's a message" or 5 or even a variable by itself $PID what you're implicitly doing is calling Write-Output against that value.
That returns the object to the pipeline, and it gets added to the objects that that returns. So in a function, it's the return value of the function, in a ForEach-Object block it's the return value of the block, etc. This bubbles all the back up the stack / pipeline.
When it has nowhere higher to go, the host handles it.
The console host (powershell.exe) or ISE host (powershell_ise.exe) handle this by displaying the object on the console; this just happens to be the way they handle it. Another host (a custom C# application for example can host the powershell runtime) might handle it differently.
So what's happening here is that you are returning the message that you want to display, as part of the return value of your function, which is not what you want.
Instead, you should use Write-Host, as this writes directly to the host, skipping the pipeline. This is the correct command to use when you want to display a message to the user that must be shown (for other information you can use different commands like Write-Verbose, Write-Warning, Write-Error, etc.).
Doing this will give you the correct result, and prevent your informational message from being part of the return value of your function.
Speaking of which, you are returning the value twice. You don't need to do:
$UserValue
return $UserValue
The first one returns the value anyway (see the top of this answer); the second one does the same thing except that it returns immediately. Since it's at the end of the function anyway, you can use wither one, but only use one.
One more note: do not call PowerShell functions with parentheses:
$test = GetUserInputValue("test")
This works only because the function has a single parameter. If it had multiple params and you attempted to call it like a method (with parentheses and commas) it would not work correctly. You should separate arguments with spaces, and you should usually call parameters by name:
$test = GetUserInputValue "test"
# better:
$test = GetUserInputValue -InputValue "test"
I am trying to create a script using mongo shell in Robo3T, where I can get returned all the latest dates of users that have submitted to userhistories. Although for some reason this script wont work. I am trying to compare 2 rows and then print the date if the ID is the same.
function lastDate(userID) {
print(db.userhistories.find({"user": userID}).sort({date:1}).limit(1));
}
lastDate(db.users.find().forEach(function(val){ val._id.toString()}));
What is wrong with this script? Or is there a better way to fix this issue??
I came across this weird issue in Powershell (not in other languages). Could anyone please explain to me why this happened?
I tried to return a specified number (number 8), but the function keeps throwing everything at me. Is that a bug or by design?
Function GetNum() {
Return 10
}
Function Main() {
$Number10 = GetNum
$number10 #1 WHY NO OUTPUT HERE ??????? I don't want to use write host
$result = 8 # I WANT THIS NUMBER ONLY
PAUSE
return $result
}
do {
$again = Main
Write-Host "RESULT IS "$again # Weird Result, I only want Number 8
} While ($again -eq 10) # As the result is wrong, it loops forever
Is that a bug or by design?
By design. In PowerShell, cmdlets can return a stream of objects, much like using yield return in C# to return an IEnumerable collection.
The return keyword is not required for output values to be returned, it simply exits (or returns from) the current scope.
From Get-Help about_Return (emphasis added):
The Return keyword exits a function, script, or script block. It can be
used to exit a scope at a specific point, to return a value, or to indicate
that the end of the scope has been reached.
Users who are familiar with languages like C or C# might want to use the
Return keyword to make the logic of leaving a scope explicit.
In Windows PowerShell, the results of each statement are returned as
output, even without a statement that contains the Return keyword.
Languages like C or C# return only the value or values that are specified
by the Return keyword.
Mathias is spot on as usual.
I want to address this comment in your code:
$number10 #1 WHY NO OUTPUT HERE ??????? I don't want to use write host
Why don't you want to use Write-Host? Is it because you may have come across this very popular post from PowerShell's creator with the provocative title Write-Host Considered Harmful?
If so, I encourage you to read what I think is a great follow-up/companion piece by tby, titled Is Write-Host Really Harmful?
With this information, it should be clear that as Mathias said, you are returning objects to the pipeline, but you should also be armed with the information needed to choose an alternative, whether it's Write-Verbose, Write-Debug, or even Write-Host.
If I were going to be opinionated about it, I would go with Write-Verbose, altering your function definition slightly in order to support it:
function Main {
[CmdletBinding()]
param()
$Number10 = GetNum
Write-Verbose -Message $number10
$result = 8 # I WANT THIS NUMBER ONLY
PAUSE
$result
}
When you invoke it by just calling $again = Main you'll see nothing on the screen, and $again will have a value of 8. However if you call it this way:
$again = Main -Verbose
then $again will still have the value of 8, but on the screen you'll see:
VERBOSE: 10
likely in differently colored text.
What that gives is not only a way to show the value, but a way for the caller to control whether they see the value or not, without changing the return value of the function.
To drive some of the points in the articles home further, consider that it's not necessarily necessary to invoke your function with -Verbose to get that.
For example, let's say you stored that whole script in a file called FeelingNum.ps1.
If, in addition to the changes I made above, you also add the following to the very top of your file:
[CmdletBinding()]
param()
Then, you still invoked your function "normally" as $again = Main, you could still get the verbose output by invoking your script with -Verbose:
powershell.exe -File FeelingNum.ps1 -Verbose
What happens there is that using the -Verbose parameter sets a variable called $VerbosePreference, and that gets inherited on each function called down the stack (unless it's overridden). You can also set $VerbosePreference manually.
So what you get by using these built-in features is a lot of flexibility, both for you as the author and for anyone who uses your code, which is a good thing even if the only person using it is you.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Is it possible to pass parameters by reference using call_user_func_array()?
I have the following line of code which worked in PHP 5.1, but isn't working in PHP 5.3.
$input = array('ss','john','programmer');
call_user_func_array(array($mysqli_stmt, 'bind_param'), $input);
In PHP 5.3, I get the following warning message:
Warning: Parameter 2 to mysqli_stmt::bind_param() expected to be a reference, value given in /var/www/startmission/em/class/cls.data_access_object.php on line 785
I changed the code to the following and it worked:
$a = 'johnl';
$b = 'programmer';
$mysqli_stmt->bind_param('ss',$a,$b);
I found this in the php documentation:
Care must be taken when using mysqli_stmt_bind_param() in
conjunction with call_user_func_array(). Note that
mysqli_stmt_bind_param() requires parameters to be passed by reference,
whereas call_user_func_array() can accept as a parameter a list of
variables that can represent references or values.
So my question is, how do I replicate the functionality of the call_user_func_array + bind_params such that i can dynamically bind variables at run time?
I found the answer to my problem in a user note by fabio at kidopi dot com dot br3 years ago on the PHP manual page of mysqli_stmt::bind_param() (slightly modified):
I used to have problems with call_user_func_array and bind_param after migrating to php 5.3.
The cause is that 5.3 requires array values as reference while 5.2 worked with real values (but also with references). So I created a secondary helper function to help me with this:
function refValues($arr)
{
$refs = array();
foreach ($arr as $key => $value)
{
$refs[$key] = &$arr[$key];
}
return $refs;
}
and changed my previous function from:
call_user_func_array(array($this->stmt, "bind_param"), $this->values);
to:
call_user_func_array(array($this->stmt, "bind_param"), refValues($this->values));
This way my db functions keep working in PHP 5.2/5.3 servers.