PowerShell V3 is RTM!

You heard it! PowerShell V3 is now available to download as RTM! It is already installed on the RTM versions on Windows 8 and Windows Server 2012.

For the down level systems (Windows 2008, 200R2 and Windows 7), you can find the downloads available here:

http://www.microsoft.com/en-us/download/details.aspx?id=34595

Enjoy!!

Posted in News, powershell, V3 | Tagged , , | 1 Comment

Converting Bytes To The Largest Type Using P/Invoke

A good while back I wrote an article (one of my first) that showed a way to convert the raw bytes of a file or anything for that matter into the upper most value. For instance, if you had 100240 bytes, it would tell you that you had 97.890625 KB instead of having to work down the line using the <bytes> / 1KB/MB/GB  approach to find the highest possible type.

I figured that there had to a better way to do this and the code I used back then was fairly bad Smile. Looking around I found that the Win32 API for doing this conversion:

[DllImport("Shlwapi.dll", CharSet = CharSet.Auto)]
public static extern long StrFormatByteSize( long fileSize, System.Text.StringBuilder buffer, int bufferSize );

If you’ve never worked with Win32 APIs before, then I strongly suggest you check out the p/invoke site here: http://pinvoke.net as it will give you lot of great information on different things you can do.

Back to the current situation. With the code above, I can plug that into a Here-String and then use Add-Type to load the code up into current PowerShell session.

$Signature = @"
[DllImport("Shlwapi.dll", CharSet = CharSet.Auto)]
public static extern long StrFormatByteSize( long fileSize, System.Text.StringBuilder buffer, int bufferSize );
"@
$Global:ConvertSize = Add-Type -Name SizeConverter -MemberDefinition $Signature -PassThru

Now that we have this, we can look at the static method that will be used for the conversion.

$ConvertSize::StrFormatByteSize

image

Here we can see that this method requires the filesize in bytes, a stringbuilder object as the buffer and the capacity property of the stringbuilder object in order to properly go through the conversion.

$stringBuilder = New-Object Text.StringBuilder 1024
$stringBuilder

image

With the StringBuilder object built, we can now try out the method with a byte size.

 $ConvertSize::StrFormatByteSize( 1256896523, $stringBuilder, $stringBuilder.Capacity )

 

image

Well, that isn’t too useful, now is it? We need to actually go back to our buffer, the StringBuilder object and get the value as a string.

$stringBuilder.ToString()

image

Now that is a lot better! Now we can use this for as long as the PowerShell session is active. Of course, a better approach is to wrap this up in a function, which I luckily did!

There were some issues while trying to write this as a function, namely loading the code up via Add-Type. This is because once you load up the code, you cannot do it again in the same session nor can you remove the type, so the function will fail if being used. To work around this, I create a global variable for the $ConvertSize object on the initial run of the function (which will cause to it be slow the first time) and then it will check for that variable and avoid trying to re-create the type (speeding things up).

The function is called Convert-Size and it does accept value from the pipeline. Here are a couple of examples.

Convert-Size -Size 56895623

image

Get-ChildItem -File | 
    Select -First 5 | 
        Select Name, 
        @{L='Size';E={$_ | Convert-Size}}

Download

Technet Script Repository

Posted in powershell, scripts | Tagged , , , , | 1 Comment

PowerShell Deep Dive Book

Now that we have been given the go ahead to announce it, I can now say that I am going to be contributing to a “PowerShell Deep Dive” book with a number of PowerShell superstars! I am very excited about this to want to thank Jeffery Hicks for giving me this great opportunity to help contribute in yet another way to the PowerShell community.

The details around the book will remain secret for right now, but I can tell you that it is going to be great! As it gets closer to the publishing time, I will post more information regarding it, so stay tuned!

The list of fellow authors in no particular order:

Name
Blog Twitter
Jeffery Hicks http://jdhitsolutions.com/blog/ JeffHicks
Grzegorz Gaêzowski http://gsgalezowski.pl/ gsgalezowski
Ben Miller http://sqlblog.com/blogs/ben_miller/default.aspx dbaduck
Jason Helmick  http://www.jasonhelmick.com/ theJasonHelmick
Don Jones http://powershell.com/cs/blogs/donjones/default.aspx ConcentratedDon
Ed Wilson http://blogs.technet.com/b/heyscriptingguy ScriptingGuys
Adam Driscoll  http://csharpening.net/ AdamDriscoll
Richard Macdonald http://blogs.technet.com/b/richard_macdonald/ _RichMac
Kirk Munro http://poshoholic.com/ PoSHoholic
Matthew Reynolds  http://social.technet.microsoft.com/profile/matthew%20reynolds%20%5Bmsft%5D/?ws=usercard-hover N/A
Tome Tanasovski http://powertoe.wordpress.com/ ToeNuff
Donabel Santos http://www.sqlmusings.com/ sqlbelle
Robert C Cain  http://arcanecode.com/ arcanecode
Richard Siddaway http://richardspowershellblog.wordpress.com/ RSiddaway
Sean Kearney http://www.powershell.ca/ EnergizedTech
Arnaud Petitjean http://www.powershell-scripting.com/ apetitjean
James O’Neill http://jamesone111.wordpress.com/ JamesONeill
Jonathan Medd http://www.jonathanmedd.net/ JonathanMedd
Chris Bellée  http://blogs.technet.com/b/heyscriptingguy/archive/tags/chris+bellee/ N/A
Trevor Sullivan http://trevorsullivan.net/ PCGeek86
Josh Gavant  http://blogs.msdn.com/b/besidethepoint/ JoshuGav
Karl Prosser http://karlprosser.com/ KarlProsser
Arvind Shyamsundar http://blogs.msdn.com/b/arvindsh/ arvisam
Jim Christopher http://www.beefycode.com/ beefarino
Jen Stirrup http://www.jenstirrup.com/ jenstirrup
Aaron Nelson http://sqlvariant.com/ sqlvariant
Doug Finke http://www.dougfinke.com/ dfinke
Jeff Wouters http://www.jeffwouters.nl/ JeffWouters

Vadims Podans http://www.sysadmins.lv/ N/A
Ashley McGlone http://blogs.technet.com/b/ashleymcglone GoateePFE
Boe Prox https://learn-powershell.net/ proxb
Bartek Bielawski http://becomelotr.wordpress.com/ Blielawb
Mike Robbins  http://mikefrobbins.com/ MikeFRobbins
Posted in Deep Dive, News, powershell | Tagged , , | 3 Comments

Reversing a String Using PowerShell

So how many times do you sit at your desk thinking “How can I easily reverse this string output?”. Probably not at all. But in the case where I needed to do this while working on a future article, I wanted to figure out an easy way to accomplish this with little to no work involved.

There are a couple of different ways to accomplish this and I will show you each of those ways. In the end, I chose going the RegEx route because it felt simpler to work with (not that the other way wasn’t much harder).

The Non-RegEx way

For this I just split out the string into an array.

$string = "This is a test, hope it works!"
$arr = $string -split ""

image

That’s a start, but we still need to still find out how to reverse everything. Luckily, [array] has a static method named… you guessed it, Reverse().

[array]::Reverse($arr)
$arr

image

Lastly, we need to bring everything back on one line.

$arr -join ''

image

Now that wasn’t too bad. But there is another way to accomplish using Regular Expressions, which I prefer.

RegEx way

Now for the regular expression way. This is basically done with one line, although in this case I set up the string in the first line.

$String = "This is a test, hope it works!"
([regex]::Matches($String,'.','RightToLeft') | ForEach {$_.value}) -join ''

 

image

As you can see, it easily takes the string and reverses it using a regular expression. I chose to use the [regex] type accelerator with the Matches() static method to make this happen. I give 3 inputs into the method: String, Pattern, Options.

For the pattern, since I want everything to get matched, I simply use the period (.) to match everything. In order to get the reverse order of all of my matches, I set the Regex options for RightToLeft, which specifies that the search will be from right to left instead of from left to right.

Here is what it looks like just showing the matches:

$String = "This is a test, hope it works!"
([regex]::Matches($String,'.','RightToLeft'))

 

image

Using ForEach looping can only grabbing the values ($_.Value), I then do use the –join operator to bring everything back together in reverse order as a single string as shown earlier.

Like I said before, I cannot think of a good use case for reversing a string, but I am sure they are out there. If you happen to have one, feel free to leave it in the comments! Because I figured someone out there might like a function to reverse strings, I put this together called Out-ReverseString. It takes a single or a collection of strings and provides the reverse string as its output.

Function Out-ReverseString {
    <#
        .SYNOPSIS
            Reverses a string

        .DESCRIPTION
            Reverses a string
        
        .PARAMETER String
            String input that will be reversed

        .NOTES
            Author: Boe Prox
            Date Created: 12August2012

        .OUTPUT System.String

        .EXAMPLE
            Out-ReverseString -String "This is a test of a string!"
            !gnirts a fo tset a si sihT

            Description
            -----------
            Reverses a string input.

        .EXAMPLE
            [string[]]$Strings = "Simple string","Another string","1 2 3 4 5 6"
            $Strings | Out-ReverseString

            gnirts elpmiS
            gnirts rehtonA
            6 5 4 3 2 1

            Description
            -----------
            Takes a collection of strings and reverses each string.
    #>
    [cmdletbinding()]
    Param (
        [parameter(Mandatory=$True,ValueFromPipeline=$True)]
        [HelpMessage("Enter a String or collection of Strings")]
        [ValidateNotNullOrEmpty()]
        [string[]]$String
    )
    Process {
        ForEach ($Item in $String) {
            ([regex]::Matches($Item,'.','RightToLeft') | ForEach {$_.value}) -join ''
        }
    }
}
Posted in powershell | Tagged , , , | 9 Comments

Locating Mount Points Using PowerShell

Sometimes when you are building a file server (or some other server), you come to realize that you have more drive or partitions than drive letters that are available. In this situation, what do you do? If you answered ‘create a mount point’ to handle this issue, then you are on the right path, or at least taking that path that I am going on.

Mount points can be defined as:

Volume Mount Points are specialized NTFS filesystem objects which are used to mount and provide an entry point to other volumes. Mount points can be created in a directory on an NTFS file system, which gives a reference to the root directory of the mounted volume.

Source

If you want to know how to create a mount point, check out this link here.

I have created 2 mount points, as you can see in the pictures below.

image image

image

In PowerShell, we can typically use Win32_LogicalDisk to find out information about each drive and its space. But guess what? This will not work so well with mount points.

Get-WmiObject Win32_LogicalDisk

 

image

Hmm, so if we cannot use the Win32_LogicalDisk class to locate these elusive mount points and find out their size, what could we use instead to figure this out? The answer lies with the Win32_Volume class instead. Whereas the Win32_LogicalDisk “represents a data source that resolves to an actual local storage device on a computer system running Windows”, the Win32_Volume class “represents an area of storage on a hard disk”. This means that even mount points will be available to us to view all sorts of information on. Because there will be a lot of data returned if I just query the class, I am only going to return what I need initially, which is the Name, Caption, FreeSpace  and Capacity.

Get-WmiObject Win32_Volume | Format-Table Name, Label, FreeSpace, Capacity

 

image

Perfect! You can see the mount points listed here in the output along with their free space and total size. Now I will take this a step further by cleaning up some of the output by removing the DVD-Drive (E:\) and converting the space from bytes to GB. I can filter by DriveType for only 3, which means I am only looking for a local disk and I can convert the bytes to GB simply by taking each value and dividing by 1GB.

Get-WmiObject Win32_Volume -Filter "DriveType='3'" | ForEach {
    New-Object PSObject -Property @{
        Name = $_.Name
        Label = $_.Label
        FreeSpace_GB = ([Math]::Round($_.FreeSpace /1GB,2))
        TotalSize_GB = ([Math]::Round($_.Capacity /1GB,2))
    }
}

image

So there you have it! Finding a mount point is not only easy to do, but also provides you with the amount of space as well! There are many other properties that you may find useful such as the serial number, block size and file system.

Also, I felt it was worth pointing out that there are some great methods associated with the Win32Volume class that are very useful. They are:

Method

Description
AddMountPoint Adds a mount point directory for the volume.
Chkdsk Invokes the Chkdsk operation on the volume.
Defrag Defragments the volume.
DefragAnalysis Generates a fragmentation analysis for the volume.
Dismount Dismounts a volume from the file system.
ExcludeFromAutoChk Excludes volumes from the Chkdsk operation to be run at the next reboot.
Format Formats the volume.
Mount Mounts a volume to the file system.
ScheduleAutoChk Schedules Chkdsk to be run at the next reboot if the dirty bit of the volume is set.

Feel free to give them a checkout and see how cool they are!

Posted in powershell | Tagged , , | 13 Comments