Showing posts with label Powershell. Show all posts
Showing posts with label Powershell. Show all posts

Tuesday, December 15, 2009

Windows Powershell v2

For whatever reason it just seems impossible for any search engine to provide the correct link to download PowerShell 2 so I'm making a note of it here on my blog so that I can easily find it again:

http://connect.microsoft.com/windowsmanagement/Downloads

 

Tuesday, November 17, 2009

Get Powershell Version Number

I wish that they'd aliased the old DOS "ver" command to Powershell's Get-Host command.

If you type "alias" at the Powershell command prompt you'll see a ton of aliases that they've setup. "dir", "copy", "cls", "compare", "md", "cd" etc. These greatly ease the transition to Powerhsell's commands if you want to quickly drop in to a command prompt and have a PowerDOS environment.

I know that I can easily configure Powershell to alias "ver" but the only time I usually need this is when I'm on a new machine and don't know what version is running. After that I don't need it anymore. Even "Get-Ver" would be more helpful and logical than Get-Host.

Anyway, if you haven't figured it out by now:

ver = Get-Host

 

Thursday, April 9, 2009

Powershell script to remove empty directories

Here's  a Powershell script that I've just created to remove empty folders which I'm sure I'm not going to need again in the future.

$items = Get-ChildItem -Recurse

foreach($item in $items)
{
      if( $item.PSIsContainer )
      {
            $subitems = Get-ChildItem -Recurse -Path $item.FullName
            if($subitems -eq $null)
            {
                  "Remove item: " + $item.FullName
                  Remove-Item $item.FullName
            }
            $subitems = $null
      }
}

 

 

Powershell Copy-Item does not honor the exclude parameter

I've been having a hard time getting Powershell's Copy-Item to work for me. My problem is that the -exclude parameter for the Copy-Item only honors the excluded items for the root directory in the destination but not for sub-directories if you also include the recurse parameter.

I believe that I have finally solved the problem with this snippet of powershell:

$source = 'd:\t1'

$dest = 'd:\t2'

$exclude = @('*.pdb','*.config')

$items = Get-ChildItem $source -Recurse -Exclude $exclude

foreach($item in $items)

{

      $target = Join-Path $dest $item.FullName.Substring($source.length)

      if( -not( $item.PSIsContainer -and (Test-Path($target))))

      {

            Copy-Item -Path $item.FullName -Destination $target

      }

}

Friday, June 27, 2008

Powershell replace text in files and recurse subdirectories

I needed to go through every file in a folder and all of its sub directories and open each file and replace a given string. This is what I finally came up with. I'm sure that this can be improved on though...

function ReplaceText($fileInfo)
{
    if( $_.GetType().Name -ne 'FileInfo')
    {
        # i.e. reject DirectoryInfo and other types
         return
    }
    $old = 'my old text'
    $new = 'my new text'
    (Get-Content $fileInfo.FullName) | % {$_ -replace $old, $new} | Set-Content -path $fileInfo.FullName
    "Processed: " + $fileInfo.FullName
}

$loc = 'c:\my file\location'
cd $loc
$files = Get-ChildItem . -recurse

$files | % { ReplaceText( $_ ) }

Saturday, June 7, 2008

Introduction to Powershell for Developers

From: Desert Code Camp 2007
Speaker: Anthony Park

Notes:

Basics:

{ - delineates a block of code.

$ - precedes a variable

-eq is 'equal'

-ne is 'not equal'

= is assignment

Store time intensive command results in a variable for later use.

e.g.: $b = Get-EventLog System

$_ is the self (this) variable.

Pipe variable or command results into the Get-Member command to see members of the object. eg: $b | Get-Member

To group a collection by one of the fields pipe the collection into the Group-Object and specify the member name as the following parameter. e.g. $b | Group-Object Source

You should sort the collection before grouping. e.g. $b | Sort-Object Source | Group-Object Source

You can filter a collection before (or after) applying the above command using the Where-Object. e.g. $b | Where-Object { $_.Source.StartsWith('S') } | Sort-Object Source | Group-Object Source

The $profile variable holds the default profile that gets run when you open Powershell. If you want to customize your Powershell then typing $profile in the Powershell environment will show you where your default profile is so that you can edit it.

 To retrieve a web page into a variable try: $mypage = (New-Object Net.WebClient).DownloadString('http://guyellisrocks.com')

 

 

Thursday, May 22, 2008

Powershell Get-ChildItem - FileSystemInfo or Array

I've just discovered something interesting in my ventures into Powershell. If a directory has a single file in it then the Get-ChildItem in that directory will return a System.IO.FileSystemInfo object but if there are 2 or more files then it will return a System.Array object.

I'm running a script and in the script I'm getting a count of the number of files in each of several directories. So what I've found that I have to do is to check the value of the "count" member return and if it's null then I assume that the object is a System.IO.FileSystemInfo object and call the Directoy.GetFiles().count member to get the number (1) of files in there.

This is what that little snippet in my Powershell script looks like now:

        $fileCollection = Get-ChildItem $s
        if($fileCollection -eq $null)
        {
            $fileCount = 0
        }
        else
        {
            $fileCount = $fileCollection.count
        }
       
        if($fileCount -eq $null)
        {
            # This happens if a directory has 1 file in it. Instead of receiving an Array object back
            # from the Get-ChildItem call we receive a System.IO.FileSystemInfo object and we need
            # to call the Directoy.GetFiles().count on that to get the right value.
            $fileCount = $fileCollection.Directory.GetFiles().count
        }
        $totalFileCount += $fileCount
 

Saturday, April 26, 2008

Powershell Ripped Media Renaming Script

I recently bought a book on CD and ripped it to .wma so that I could listen to it on my portable media player. When the tracks rip to disk they get named with the track number starting first. I wanted to rename the files so that the two digit disc number preceded the track number so that I could sort all of the tracks in one folder and listen to them in the correct order. Here's a Powershell script that I ran from the folder one below the ripped discs' folders.

# change directory into root of ripped files
cd "D:\Audio\Author Name"
$dirr = "BookName Disc "
$discs = 1..7 # Change to number of discs

foreach($disc in $discs)
{
    $discdir = $dirr + $disc.ToString()
    cd $discdir
    $dir = get-childitem *.wma
    foreach($x in $dir)
    {
        $newname = "0" + $disc.ToString() + "." + $x.Name.SubString(0,2) + ".wma"
        Rename-Item $x $newname
    }
    cd ..
}

I've updated the code that appeared here before 8 July 2010. Previously it did not have the loop for each disc. This code still isn't perfect. Instead of prepending the 0 to the disc number when creating the new name I should be formatting the disc value.

Wednesday, April 23, 2008

Download List of Files from Web with Powershell Script

I recently came across Scott Hanselman's Hansel Minutes and it looked like the sort of thing that I wanted to listen to. At the time I found it the archives had 109 podcasts. I wanted to download them all and stick them on my MP3 player but didn't want to click through to each link and repeat myself 109 times. I'm a big fan of the DRY principal. So I wrote a Powershell script to do it for me.

First off I examined the file naming pattern:

http://perseus.franklins.net/hanselminutes_0001.wma

to

http://perseus.franklins.net/hanselminutes_0109.wma

Fantastically simple. You couldn't ask for a nicer pattern.

So here's the script:

function main()
{
    $clnt = new-object System.Net.WebClient

    $sourceNames = 1..109 |%{"hanselminutes_{0:0000}.wma" -f $_}
    foreach($s in $sourceNames)
    {
        $url = "http://perseus.franklins.net/" + $s
        $target = "c:\temp\" + $s
        write-host 'transfering from' $url 'to' $target
        $clnt.DownloadFile($url, $target)
    }
}

main

 

During the execution of the script over the 109 files that were in the archive at the time 3 files failed because of a timeout and 2 files failed because they didn't follow the naming pattern: The interviews with Jonathan Zuck and Robert Pickering (#'s 86 and 76 respectively) had their names tagged on to the file names.

Saturday, April 5, 2008

Powershell Grep

For whatever reason I always forget the syntax to quickly find text in a bunch of source files from Powershell. Here it is so I can quickly look it up again:

Get-ChildItem -include *.cs -recurse | Select-String "string to search for"

The Get-ChildItem is the equivalent of dir in DOS.

-include is the param to tell Get-ChildItem which files to include in its search. In this case all CSharp (C#) files.

-recurse means look in subfolders under this one as well. i.e. the one that I'm running the command from.

| - this is the pipe symbol. The results of the search (a collection of files) is piped into the process that will open each file and search for the string.

Select-String - this is the command that will open a file and search for the "string to search for" string in the file. Each found line will be listed.