Powershell

This is a work in progress but I wanted to get it out in the open for feedback.  Please leave a comment or discuss on microsoft.public.windows.powershell.  As is my custom, this is meant to be used in your interactive shell as a library.  This means you should save the contents as a file, then dot-source this file, then you can use the functions and filters.  If you like it, then you add the dot-source command to your profile and Bob’s your uncle.  (Whatever that means.)

In case you don’t know, dot-source means something like the below.  Doing it this way makes the functions available in the current scope–your interactive shell or script.

# . ./lib-util.ps1

As a bonus, since the attached file is one of my general multi-purpose library files, you get not one but count ‘em–THREE functions of arguable utility for the price of one!  Included are:

  • Get-WebFile – object-oriented utility to grab files from the net (shown below)
  • Copy-WebFile – simpler function to save a single URL to a local file
  • Load-PsSnapin (from Nivot Ink) – Lists registered, but unloaded snap-ins and allows you to load them

File attachment: lib-util.ps1

Here’s some code:

(NOTE: line 34 and others are having the underscore “_” truncated…not sure why yet but I’m working on it.  The file attachment does not have these apparent typos.)

   1: function Get-WebFile {
   2: ### function: Get-WebFile
   3: ### version: 0.3
   4: ### "It's like wget, but not."
   5: ### Input: These options can be combined, parameter or pipeline is required
   6: ###   Paramater (1) (optional):
   7: ###      -  [string] URL of file you wish to get -or-
   8: ###      -  [system.uri] URL object of file you wish to get
   9: ###   Pipeline (optional):
  10: ###     Accepts pipelined [string] or [system.uri] objects
  11: ### Output:
  12: ###   Array of [System.IO.FileSystemInfo] objects (aka files)
  13: ### thanks to BS's fine code examples found here: http://bsonposh.com/modules/wordpress/?p=18
  14:  
  15: ### TODO: 
  16: ###   - error checking, progress bar needs work
  17: ###   - what else should this do like wget?
  18:  
  19:   Param ( [system.uri]$srcUrl )
  20:  
  21:   Begin {
  22:     $webClient = new-object System.Net.WebClient
  23:     $process = @() # pipeline
  24:     $objCollection = @() # output objects
  25:   }
  26:  
  27:   Process {
  28:     if ($_) { # anything in the pipeline?
  29:       if ($_.AbsoluteUri) { # is it a string or a [system.uri] object?
  30:         $process += $_.AbsoluteUri
  31:       }
  32:       else {
  33:         $process += $_
  34:       }
  35:     }
  36:   }
  37:  
  38:   End {
  39:     if ($srcUrl) {$process += $srcUrl} # if URL was provided as parameter, add to pipeline
  40:     $i = 1
  41:     foreach ($Url in $process) {
  42:       $tempFileName = [System.IO.Path]::GetTempFileName() # use temp file to store download
  43:       if ([system.uri]$Url -eq $false) { throw "Unable to convert $Url to URL." }
  44:       $localFileName = $tempFileName # + "." + $Url.Segments[$Url.Segments.Length-1]
  45:       write-progress $Url "Total Progress ->" -percentcomplete ($i/$process.length*100)
  46:       $result = $webClient.DownloadFile($Url,$localFileName) # downloads file
  47:       $objFile = get-childitem $localFileName # gets reference to downloaded file 
  48:       $objcollection += $objFile # add reference to output object
  49:       $i++
  50:     }
  51:     Write-Output $objCollection # send down the pipeline
  52:   }
  53: }

And here’s what it looks like in use:

1# $a = get-content C:\tmp\urls.txt
2# $b = $a | Get-WebFile
3# $b.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array

5# $b[0].GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     FileInfo                                 System.IO.FileSystemInfo

6# $b

    Directory: Microsoft.PowerShell.Core\FileSystem::C:\Documents and Settings\hrottenberg\Local
    Settings\Temp

Mode           LastWriteTime       Length Name
----           -------------       ------ ----
-a---     8/23/2007  8:56 AM         8794 tmp2F.tmp
-a---     8/23/2007  8:56 AM        23358 tmp30.tmp
-a---     8/23/2007  8:56 AM        41858 tmp31.tmp

7# get-content $b[0] | Select-Object -first 5

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/x
html1-transitional.dtd">
<html>
<head>
<title>Bloglines | Log In</title>

: http://halr9000.com/article/417

2007-08-23 07:04:28

[...] script: Get-WebFile I’ve blogged it here: [link] This is meant to be sort of like wget (which people have done before in powershell–it’s very [...]

2007-09-22 14:50:39

I couldn’t understand some parts of this article , but I guess I just need to check some more resources regarding this, because it sounds interesting.

2007-09-23 09:41:41

Daniel,

Can you be more specific? I’ll write a follow up article and/or
explain it further on my PowerScripting podcast.

  • Microblog

  • Recent Posts

  • Recent Comments

  • meta

  • PowerShell Blogroll