Tuesday, April 2, 2013

Two Point Conversion

A week after I finished my last post about converting variables between data types I ran into a problem converting data types that wasn't covered by anything in the post.  Time for one more play.

In my case I needed to add a new value to the registry.  The data is different for each host and the input file lists the data values as a hexadecimal string.  The type accelerators for numeric conversion don't help in this case

How to crack that nut?  When in doubt, check if .net has any tools for us to use.  In this case there is a quite powerful system class named, appropriately enough, convert.  This is the swiss army knife of data conversion letting us convert just about any concievable combination of data classes.

In my case I needed to use one of the ToInt methods.  Registry values will be either 32 or 64 bit (dword or qword) but 64 bit will only work with newer versions of Windows.

Notice how many different possible inputs I have for ToInt32.  The one I need is the one that accepts a string and specifies the base of the string.  There are versions of this for 16 and 64 bit integers as well.   This example shows the string '1010' converted from the available bases, binary, octal, decimal, and hexadecimal.

Most of the conversion methods are straightforward and self explanitory.  The ToByte method could have worked if the hex values were small enough to fit into a single byte.

ToBoolean converts any number isn't a zero to true.  And it can interpret any string that evaluates to 'true' or 'false'.  This would be handier if it could automatically convert numeric strings to numbers or evaluate logical equivilants like 'yes' or 'no' to 'true' or 'false'.

The ToBase64 and FromBase64 methods allow some quick encoding and decoding of strings and character arrays.  Depending on the input you may have to do some massaging of the data because the ToBase64 method expects an array of bytes as input.

The GetTypeCode returns a value describing the data type of the input object.

This information comes in handy if you want to use the ChangeType method.

But that's a long way to go because we have the shortcut of using the type accelerators.  You will almost always use the built-in type accelerators but, as in dating, its nice to know you have other options.


Wednesday, March 6, 2013

Not my type

In programming languages variables can be of a specific data type, such as integers or strings of characters.  If a language requires variable to be defined as containing only a specific class of data it is called strongly typed.  If the variables can contain any kind of data the language is weakly typed.  If the language is experimental it is prototyped. If it requires punch cards it is teletyped

http://www.staff.ncl.ac.uk/roger.broughton/museum/iomedia/images/pc6.jpg

As mentioned previously, everything in PowerShell is an object.  But simple scalar variables still have a data type.  PowerShell makes a best guess at what the type should be and does conversions on the fly so you usually don't have to worry about the data type of a variable or performing explicit conversions.


Here PowerShell converts the string to an integer, multiplies it with the floating point number, then adds the hexadecimal number.  When I give the answer it converts the integer to a string so it can be concatenated with the rest of the text.

Most of the time PowerShell correctly determines the data type and formats the output accordingly.  But what if you need to force a variable to be a specific type?  Precede either the variable or expression with the .NET value type enclosed in square brackets.  In this example we divide two numbers and cast the result as an integer and string respectively.


But that looks like it involves a bunch of typing.  Wouldn't it be nice if there was a shortcut to access those system types?  Yes it would be nice so that's why the nice people who made PowerShell included some type accelerators.  Instead of using [System.Int32] I can use [int] and instead of [System.String] I can use [string]


Are there many of these type accelerators available?  Yes there are. Oisen Grehan 's blog post not only shows all of the accelerators available but a handy way to list them all.  One that does not show up in the list is the [DateTime] accelerator for [System.DateTime].  Notice how flexible this value type is.


Now go back and check Oisen Grehan's blog post again.  There's all kinds of useful stuff that is just as flexible as the [DateTime] accelerator.  For example, there is the [ipaddress] data type that accepts a string and converts it to an IP address.


This is pretty sweet.  Notice that the type accelerator processes both IPv4 and IPv6 addresses.  If I need to prompt my user for an IP address I don't need to parse and validate it.  I can just assign it to a variable that has the [ipaddress] type and wrap it with some error handling then let .Net and PowerShell do the heavy lifting.

One other handy accelerator is the array type.  Why is it handy?  Because it gives us access to all of the methods for the .Net array class.  To access any of the .Net class methods specify the class in square brackets followed by two colons and then the method.


Note that that when calling these methods they only operate on the variable you pass.  If you need to keep the array in its original state you need to copy it first and then call the method on the copy.


Type accelerators are one of PowerShell's many useful and time saving capabilities.  If you never introduce yourself you might not know that PowerShell is just your type.