You most likely know that I'm all about the object and the PowerShell pipeline. Everything in PowerShell is an object. Pipe something to Get-Member and you can discover all of the object's properties and methods (ie its members). Some objects, like strings, have many methods but very few properties. Some objects, like numbers have very little of either. I mean, what can you really do with a number? Well, I can have a bit of fun with one and maybe teach a few PowerShell concepts along the way.
ManageEngine ADManager Plus - Download Free Trial
Exclusive offer on ADManager Plus for US and UK regions. Claim now!
I wrote a function called Get-NumberObject. It will take any number you pass to it and create a custom number object. Here's an example of the end result:
[cc lang="PowerShell"]
PS S:\> get-numberobject 7
Log : 1.94591014905531
Tangent : 0.871447982724319
Inverse : 0.142857142857143
CircleArea : 153.9380400259
IsEven : False
IsPrime : True
Number : 7
Factorial : 5040
Cosine : 0.753902254343305
Exp : 1096.63315842846
Sqrt : 2.64575131106459
Sine : 0.656986598718789
Square : 49
Cube : 343
Factors : {1, 7}
[/cc]
What I'm really doing is having some fun with the [Math] .NET class. This class has a number of methods for performing an operation on a number such as calculating its square root. Here's the code and then I'll go through a few key points.
[cc lang="PowerShell"]
Function Get-NumberObject {
Param(
[Parameter(Position=0,Mandatory=$True,HelpMessage="Enter an number greater than 0",
ValueFromPipeline=$True)]
[alias("x")]
[ValidateScript({$_ -gt 0})]
[object[]]$Number,
[scriptblock]$Custom
)
Begin {
Function Test-IsEven {
Param($x)
if ($x%2 -eq 0) {
$True
}
else {
$False
}
} #Test-IsEven
Function Test-IsPrime {
#http://www.wikihow.com/Check-if-a-Number-Is-Prime
Param($x)
if ($x -eq 1) {
Write $False
}
Else {
$Prime=$True
for ($i=2;$i -le ([math]::Sqrt($x));$i++) {
$z=$x/$i
if ($z -is [int]) {
$Prime=$False
Break
}
} #for
Write $Prime
} #else
} #test-isprime
} #begin
Process {
foreach ($N in $number) {
#define a hash table of values from some math operations
$hash=@{
Number=$N
Square=($N*$N)
Cube=[math]::Pow($N,3)
Sqrt=[math]::Sqrt($N)
Log=[math]::Log($N)
Sine=[math]::Sin($N)
Cosine=[math]::Cos($N)
Tangent=[math]::Tan($N)
CircleArea=[math]::PI*($N*$N)
Inverse=1/$N
IsEven=(Test-IsEven $N)
IsPrime=(Test-IsPrime $N)
Exp=[math]::Exp($N)
Factorial= (1..$N |foreach -begin {$r=1} -process {$r*=$_} -end {$r})
Factors=(1..$N | where {$N/$_ -is [int]})
}
#if a custom calculation was passed, invoke it and add the value to the hash table
if ($Custom) {
$hash.Add("Custom",(Invoke-Command -ScriptBlock $custom -ArgumentList $N))
}
#use the hash tables as proprties for an object
$obj=New-Object -TypeName PSObject -Property $hash
#let's add some methods
$obj | Add-Member -MemberType ScriptMethod -Name ToBinary -value {[convert]::ToString($this.number,2)}
$obj | Add-Member -MemberType ScriptMethod -Name ToOctal -value {[convert]::ToString($this.number,8)}
$obj | Add-Member -MemberType ScriptMethod -Name ToHex -value {[convert]::ToString($this.number,16)} -PassThru
} #foreach
} #process
End {
#this is not used
}
} #end function
[/cc]
The function takes a number as a parameter. I'll come back to the Custom parameter in a bit. The function includes two nested functions to determine if a number is even and one to determine if it is prime. Feel free to write you own algorithms but these work reasonable well. The main part of the function creates a custom object. The object's properties are common math operations.
[cc lang="PowerShell"]
#define a hash table of values from some math operations
$hash=@{
Number=$N
Square=($N*$N)
Cube=[math]::Pow($N,3)
Sqrt=[math]::Sqrt($N)
Log=[math]::Log($N)
Sine=[math]::Sin($N)
Cosine=[math]::Cos($N)
Tangent=[math]::Tan($N)
CircleArea=[math]::PI*($N*$N)
Inverse=1/$N
IsEven=(Test-IsEven $N)
IsPrime=(Test-IsPrime $N)
Exp=[math]::Exp($N)
Factorial= (1..$N |foreach -begin {$r=1} -process {$r*=$_} -end {$r})
Factors=(1..$N | where {$N/$_ -is [int]})
}
[/cc]
I'm going to trust that you have enough math background to understand the different operations. The end result is a hash table that I will use as property names and values.
[cc lang="PowerShell"]
#use the hash tables as proprties for an object
$obj=New-Object -TypeName PSObject -Property $hash
[/cc]
I also added a parameter called -Custom. This parameter expects a scriptblock like this:
[cc lang="PowerShell"]
{Param($x) [math]::Pow(10,$x)}
[/cc]
The scriptblock should take a value as a parameter because whatever number you pass to Get-NumberObject will be passed to this scriptblock.
[cc lang="PowerShell"]
#if a custom calculation was passed, invoke it and add the value to the hash table
if ($Custom) {
$hash.Add("Custom",(Invoke-Command -ScriptBlock $custom -ArgumentList $N))
}
[/cc]
But wait...there's more! I thought, "Don't try to do everything. What about adding some methods to the object?" So I did. I took the custom object and piped it to Add-Member where I added a few ScriptMethods. The value of the scriptmethod is a scriptblock where you use $this to reference the object itself, not $_. I created methods ToBinary(), ToOctal() and ToHex().
[cc lang="PowerShell"]
#let's add some methods
$obj | Add-Member -MemberType ScriptMethod -Name ToBinary -value {[convert]::ToString($this.number,2)}
$obj | Add-Member -MemberType ScriptMethod -Name ToOctal -value {[convert]::ToString($this.number,8)}
$obj | Add-Member -MemberType ScriptMethod -Name ToHex -value {[convert]::ToString($this.number,16)} -PassThru
[/cc]
Don't forget to add -Passthru to the last item, otherwise your object won't get written to the pipeline. But now I get a "real" object. GNO is an alias for my function.
I can see the object:
[cc lang="PowerShell"]
PS S:\> $n
Log : 2.56494935746154
Tangent : 0.46302113293649
Inverse : 0.0769230769230769
CircleArea : 530.929158456675
IsEven : False
IsPrime : True
Number : 13
Factorial : 6227020800
Cosine : 0.907446781450196
Exp : 442413.39200892
Sqrt : 3.60555127546399
Sine : 0.420167036826641
Square : 169
Cube : 2197
Factors : {1, 13}
[/cc]
I can even call the methods:
[cc lang="PowerShell"]
PS S:\> $n.tobinary()
1101
PS S:\> $n.tooctal()
15
PS S:\> $n.tohex()
d
[/cc]
The bottom line is that I created a rich object that can be written to the pipeline.
[cc lang="PowerShell"]
PS S:\> 1..11 | get-numberobject | select Number,Sqrt,Square,Cube,Factorial | format-table -auto
Number Sqrt Square Cube Factorial
------ ---- ------ ---- ---------
1 1 1 1 1
2 1.4142135623731 4 8 2
3 1.73205080756888 9 27 6
4 2 16 64 24
5 2.23606797749979 25 125 120
6 2.44948974278318 36 216 720
7 2.64575131106459 49 343 5040
8 2.82842712474619 64 512 40320
9 3 81 729 362880
10 3.16227766016838 100 1000 3628800
11 3.3166247903554 121 1331 39916800
[/cc]
If you aren't taking advantage of objects in the pipeline, then you might as well be writing VBScript. Look for objects. Find their members. And if you can't find an object that meets your need, create one!
Download Get-NumberObject and let me know what you think.