I want to assign a variable to a function. For example, let’s suppose I have variable A. I want variable A to return a random number through the Get-Random method. How do I do that? If I do something like $a = function Test(){Get-Random}
, it doesn’t work (it shows nothing as result). If I do $a = {Get-Random}
, it returns a script block when I type $a
. How could I achieve my want? I want to know how to set a variable as a function return result so that I may define object classes variables as functions so that I can “define” object instantiation object (The variables declared with a syntax such as follows: $A = New-Object ClassName
) variables in a quite customized fashion. Can script blocks and invoke expressions help me in that endeavor? Thanks.
I’m unsure if I got what you mean. Why don’t you call the function directly?
I want a variable to be assigned as an expression/function, and, as such, when the variable is called, the expression/function in which the variable represents is called. For example, $A = Get-Random;
, from the time I assign the variable $A
to the expression/function Get-Random;
, I want the variable $A
to return a random number every time it is called, and same with something like $A = Function GetRandomNumber(){Get-Random;}
, I know these examples do not work according my wants, and I’m just giving an illustrative example.
That’s not what I want. I want to be capable of assigning an expression/function to a variable so that I may do that with variables of objects of classes. This example illustrates what I want (I’ve modified a part of directories to ‘REDACTED’):
PS C:\Users\REDACTED> Class ExampleClass
>> {
>> $ExampleVariable = "10";
>> [Int]ExampleFunction(){return Get-Random -Maximum (Invoke-Expression $this.ExampleVariable);}
>> }
PS C:\Users\REDACTED> $ExampleObject = New-Object ExampleClass;
PS C:\Users\REDACTED> $ExampleObject.ExampleFunction();
3
PS C:\Users\REDACTED> $ExampleObject.ExampleVariable = "Get-Random -Minimum 10 -Maximum 21";
PS C:\Users\REDACTED> $ExampleObject.ExampleFunction();
8
PS C:\Users\REDACTED> $ExampleObject.ExampleVariable
Get-Random -Minimum 10 -Maximum 21
PS C:\Users\REDACTED> $ExampleObject.ExampleFunction();
1
PS C:\Users\REDACTED> $ExampleObject.ExampleFunction();
13
PS C:\Users\REDACTED> $ExampleObject.ExampleFunction();
7
PS C:\Users\REDACTED> $ExampleObject.ExampleFunction();
0
PS C:\Users\REDACTED> $ExampleObject.ExampleFunction();
12
PS C:\Users\REDACTED> $ExampleObject.ExampleFunction();
11
PS C:\Users\REDACTED> $ExampleObject.ExampleFunction();
12
PS C:\Users\REDACTED> $ExampleObject.ExampleFunction();
6
PS C:\Users\REDACTED> $ExampleObject.ExampleFunction();
8
PS C:\Users\REDACTED> $ExampleObject.ExampleFunction();
9
PS C:\Users\REDACTED> $ExampleObject.ExampleFunction();
9
PS C:\Users\REDACTED> $ExampleObject.ExampleFunction();
3
PS C:\Users\REDACTED> $ExampleObject.ExampleFunction();
12
PS C:\Users\REDACTED> $ExampleObject.ExampleFunction();
10
PS C:\Users\REDACTED> $ExampleObject.ExampleFunction();
9
PS C:\Users\REDACTED> $ExampleObject.ExampleFunction();
4
PS C:\Users\REDACTED>
In this code, I assign the string value “10” to ExampleVariable, so the ExampleFunction is supposed to return a value that is either 0 or an int value between 0 and 10. When I assign string variable ExampleVariable to a string which represents an expression/function that is supposed to return a number (let’s say “A”) that is either 10 or an int between 10 and 21, the function ExampleFunction is supposed to return a number that is either 0 or a number between 0 and A. As you see in the results, there are unexpected results, such as Powershell returning the int 8 when it would be something not possible if the Powershell was functioning correctly, and that happened because the expression/function Invoke-Expression
appears to have a tendency to generate problems. What I want is for me to be capable of doing the same thing I did, for example, however without having to “evaluate” any strings and transforming them into expressions/functions, just like I’ve exemplified in the text above the code at the beginning of the response.
What’s the difference between
`Something`
And
`$Something`
?
For the end user, it’s a difference of typing one less character. However, one of these can do what you’re asking for, the other needs additional work to do what you want. Instead of storing a function in a variable, just type the function name.
Function Something {
‘Code’
}
Simply call it like normal
Something
If you insist on storing it in a variable, I would make it a scriptblock.
$something = {
Function Something {
‘Code’
}
Something
}
Then you can call it like
. $something
Or
& $somethhng
Doesn’t it seem easier, cleaner, and more logical to just stick with a function?
I got this. But it still does not make any sense to me. What would be the advantage of using a variable running a function when called over a normal plain old function call?
It looks to me like it is functioning correctly. When you assign the expression “Get-Random -Minimum 10 -Maximum 21” to the ExampleVariable, it is only affecting the -Maximum option of the Get-Random cmdlet within your ExampleFunction. Did you expect it to just replace the entire ExampleFunction code? It looks like that’s what you’re saying. Take another look.
Yes, you can use Script Blocks and Invoke Expression.
Script Blocks is basically anonymous function which is a common feature in every language. Anonymous function is an expression not a function. So, to get the result you have to invoke the expression using Invoke-Command
or Call Operator &
, not by typing the variable directly.
You have two choices regarding using Script Blocks to get random number from Get-Random
cmdlet.
First, after declaring $a = { Get-Random }
, you must invoke it as follows:
$a = { Get-Random }
& $a
# or
Invoke-Command $a
Second, you have to remove function Test()
statement from your function to make it anonymous since anonymous function is a function that doesn’t have a name (you may declare parameters).
So, the script will be like this:
$a = {
Get-Random
}
& $a
# or
Invoke-Command -ScriptBlock $a
References: