Using Windows PowerShell to Work with Numbers

Using Windows PowerShell to Work with Numbers

  • Comments 5
  • Likes

Microsoft Scripting Guy Ed Wilson here, the hotel we are using this weekend has free wireless access points setup throughout the facility. I decided to take my laptop with me as I headed downstairs to get some breakfast. The horse show does not begin until 10:00 A.M., and that gives me some time to catch up on email sent to scripter@microsoft.com.

Normally, I like to use the Weekend Scripter articles to do things that are more fun and interesting (I mean, after all it is the weekend for a large portion of the world). However, because the script I had intended to write did not work on my Windows 7 laptop, I felt like I needed to get something done before we head out to the horse show. I can only push my luck so far by taking my laptop to the show…

What did not work, you may ask? Well I had an idea about using another undocumented WMI class to get wireless signal strength. The WMI class MSNdis_80211_ReceivedSignalStrength is seen in the following image.

Image of WMI class MSNdis_80211_ReceivedSignalStrength

To use this WMI class in a Windows PowerShell script, use the Get-WmiObject cmdlet as shown here:

PS C:\> Get-WmiObject -Class MSNdis_80211_ReceivedSignalStrength -Namespace root/wmi
PS C:\>

The problem, as you can plainly see is that no information is returned…at least not on my 64 bit Windows 7 laptop. That is one of the problems with using undocumented WMI classes, one never knows if they will work or not.

Well, because my ideas for a really cool Weekend Scripter article were blown out of the water, I decided to open up Scripter and I came across a rather interesting email … admittedly it is not as cool as picking up your wireless signal strength via a script, but it may be a bit more useful. Here is the question … oh wait, the question is in Portuguese, and while that would be fine for my friends in Portugal, Brazil and Macau, it won’t work too well for my friends in the USA. So basically, what NG is asking is how he can use Windows PowerShell to perform mathematical calculations.

Here is my answer to him.

Windows PowerShell is designed for use by network administrators, and others who wish to work with computers. At its heart, it is an automation language that enables one to perform easy tasks such as shutting down computers, pinging computers, and starting and stopping services. Many of our network applications are using Windows PowerShell for their automation solution. This includes applications such as SharePoint server, Exchange Server, SQL Server, Internet Information Server, Active Directory Domain Services, and others.

This having been said, Windows PowerShell is a .NET Framework based application, and as a result has full support for the .NET Framework. From a mathematical perspective, you would do well to review the members of the system.math .NET Framework class. Here is a link to documentation on that class: http://msdn.microsoft.com/en-us/library/system.math.aspx All of these members are static, which means they can be used directly from within Windows PowerShell. Here is an example of using the TAN static method to return the tangent of a 45-degree angle:

PS C:\> [system.math]::tan(45)
1.61977519054386
PS C:\>

Note that I place system.math inside square brackets, and then use the double colon after that. The square brackets allow me to refer to the .NET Framework class directly without having to create an instance of it. The double colon is used to call the static method. Because Windows PowerShell assumes the system namespace, you do not need to type it if you do not wish. The decision as to whether to include it or not, will remain with you – do you remember that the math class is found in the system namespace? In general I have a tendency to forget these types of things, and therefore I tend to use the full name. You can use the static TAN method from the system.math .NET Framework class by leaving out the word system. This is shown here:

PS C:\> [math]::tan(45)
1.61977519054386
PS C:\>

Using the other static methods is just as easy. For example, if you need to know the cosign of a 90 degree angle, use the COS method. This is shown here:

PS C:\> [math]::COS(90)
-0.44807361612917
PS C:\>

As a “computer” person, I like the ability to use the Pow method. This will give me a number raised to a certain power. For example, if I need to work with binary numbers … powers of two, I can do so like this:

PS C:\> [math]::pow(2,2)
4
PS C:\> [math]::pow(2,3)
8
PS C:\> [math]::pow(2,4)
16
PS C:\> [math]::pow(2,0)
1
PS C:\>

I can even write a script to display binary numbers. If I need to work with subnet masks, the script shown here can be used:

PS C:\> 0..7 | Foreach-Object {write-host $_ ([math]::pow(2,$_)) }
0 1
1 2
2 4
3 8
4 16
5 32
6 64
7 128
PS C:\>

I could do the same thing with base 8 and base 16 if I needed to do so. NG, that is all there is to working with methods from the system.math .NET Framework class. You do not have to use MSDN to look up the class. If you have an idea about what a method might do, you can use the Get-Member cmdlet to retrieve the static methods, as shown here:

PS C:\> [math] | Get-Member -Static -MemberType method


   TypeName: System.Math

Name            MemberType Definition
----            ---------- ----------
Abs             Method     static System.SByte Abs(System.SByte value), static System.Int16 Abs(...
Acos            Method     static double Acos(double d)
Asin            Method     static double Asin(double d)
Atan            Method     static double Atan(double d)
Atan2           Method     static double Atan2(double y, double x)
BigMul          Method     static long BigMul(int a, int b)
Ceiling         Method     static decimal Ceiling(decimal d), static double Ceiling(double a)
Cos             Method     static double Cos(double d)
Cosh            Method     static double Cosh(double value)
DivRem          Method     static int DivRem(int a, int b, System.Int32&, mscorlib, Version=2.0....
Equals          Method     static bool Equals(System.Object objA, System.Object objB)
Exp             Method     static double Exp(double d)
Floor           Method     static decimal Floor(decimal d), static double Floor(double d)
IEEERemainder   Method     static double IEEERemainder(double x, double y)
Log             Method     static double Log(double d), static double Log(double a, double newBase)
Log10           Method     static double Log10(double d)
Max             Method     static System.SByte Max(System.SByte val1, System.SByte val2), static...
Min             Method     static System.SByte Min(System.SByte val1, System.SByte val2), static...
Pow             Method     static double Pow(double x, double y)
ReferenceEquals Method     static bool ReferenceEquals(System.Object objA, System.Object objB)
Round           Method     static double Round(double a), static double Round(double value, int ...
Sign            Method     static int Sign(System.SByte value), static int Sign(System.Int16 val...
Sin             Method     static double Sin(double a)
Sinh            Method     static double Sinh(double value)
Sqrt            Method     static double Sqrt(double d)
Tan             Method     static double Tan(double a)
Tanh            Method     static double Tanh(double value)
Truncate        Method     static decimal Truncate(decimal d), static double Truncate(double d)


PS C:\>

There are also two static properties that can be used. The two static properties are shown here:

PS C:\> [math] | Get-Member -Static -MemberType property


   TypeName: System.Math

Name MemberType Definition
---- ---------- ----------
E    Property   static System.Double E {get;}
PI   Property   static System.Double PI {get;}


PS C:\>

You use the same methodology to access static properties:

PS C:\> [math]::pi
3.14159265358979
PS C:\>

If you want to find the circumference of a circle, you may remember the formula 2 x pi x radius. You can do exactly the same thing using Windows PowerShell. This is shown here where I get the circumference of a circle that has a radius of 2:

PS C:\> $pi = [math]::pi
PS C:\> $r = 2
PS C:\> 2*$pi*$r
12.5663706143592
PS C:\>

You can even create a function to give you the circumference of a circle if you wish. This is shown here:

PS C:\> function get-circumference {Param($r);Return (2*[math]::pi)*$r}
PS C:\> get-circumference -r 2
12.5663706143592

NG, that is all there is to working with static properties from the system.math class. I also see my significant other standing by the door swinging the camera around like a whirligig so I should put my laptop to sleep and get ready to boogie. The cool thing is she has not given me time to put my laptop up; therefore, I will have to take it with me to the horse show—yes!

We invite you to join us tomorrow when we will begin talking about date manipulation. We would love for you to follow us on Twitter or Facebook. If you have any questions, send email to us at scripter@microsoft.com, or post them on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

 

Ed Wilson and Craig Liebendorfer, Scripting Guys

 

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • PS C:\> [system.math]::tan(45)

    1.61977519054386

    That's the tangent of an angle of 45 radians, not 45 degrees.  The tangent of 45 degrees is 1 (this is quite obvious if you draw it):

    PS C:\> [System.Math]::tan(45/180*[System.Math]::PI)

    1

    The same error is done for cosine (cos(90°) is 0).  The trigonometric functions in the .NET framework use radians for angles (and this is a better choice than degrees).

  • > using the TAN static method to return the tangent of a 45-degree angle:

    No it doesn't. That is tan(45 radians). As shown by your cos(90) example: cos(90 degrees) is 0.

    To convert degrees to radians multiply by pi/180 (using [Math]::PI of course).

  • I'm working with Powers and I have a formula that has multiple power functions within the formula. My current formula is 4*3*([Math]::Pow([Math]::Pow(.12,1.522)),([Math]::Pow(3,0.026)))

    but when I run it, it throws an error "Cannot find an overload for "Pow" and the argument count: "1""

    Help please.

  • @Dust

    Missing a zero and too many parens:

    4  *  3  *  [Math]::Pow(   [Math]::Pow(   0.12,  1.522  )  ,  [Math]::Pow( 3,  0.026 )   )

    It helps to use white space to make structure more visible.

  • @jrv

    Thanks!