views:

1034

answers:

4

Hi,

Windows PowerShell is out a quite long time now. In comparison to the the good old windows shell it's much more powerful. Are there any scripts you use to speed up and simplify your every day work as an developer? If you can do magic with PowerShell -> please share it with us!

Update Not really a script, but also very useful are PowerShell Community Extensions. The package contains a lot of new Cmdlets and PowerShell modifications.

+2  A: 

I use this one all the time because Windows Explorer's search for file contents never works for me:

Get-ChildItem -Recurse -Filter *.extension |
    Select-String -List somestring |
    Format-Table filename,linenumber -AutoSize

Just replace "extension" with the file extension of the file type you're interested in (or remove the -Filter parameter entirely) and replace "somestring" with the text you want to find in the file.

Ray Vernagus
+1  A: 

Any time you see something with proper capitalization, it's an indication I've used TAB completion. You should learn which things PS will complete for you -- it's quite good in V2.

Any time you see aliases in lowercase, it's something I typed from memory. You should memorize it too.

# grep example - find all using statements
dir -r -fil *cs | ss using
# advanced version
dir -fil *cs -r | ss '^using[^\(]+' | gpv line | sort -unique

# figure out how to query for drive free space (emphasis on "figure out" -- I can never remember things like this)
gcm *drive*
help Get-PSDrive -full
Get-PSDrive | gm
# now use it
Get-PSDrive | ? { $_.free -gt 1gb }

# pretend mscorlib.dll is an assembly you're developing and want to do some ad-hoc testing on
$system = [system.reflection.assembly]::LoadFile("c:\blah\...\mscorlib.dll")
$system | gm
$types = $a.GetTypes()    
$types | gm
$types | ? { $_.ispublic -and $_.basetype -eq [system.object] } | sort name
$sbType = $types | ? { $_.name -eq "StringBuilder" }
# now that we've loaded the assembly, we could have also done:
#   $sbType = [system.text.stringbuilder]
# but we may not have known it was in the Text namespace
$sb = new-object $sbType.FullName
$sb | gm
$sb.Append("asdf")
$sb.Append("jkl;")
$sb.ToString()
Richard Berg
+3  A: 

I put together a bunch of scripts to work with Subversion at the command line. Most of them just use the --xml option to put various information in object form. Here are a couple of examples:

function Get-SvnStatus( [string[]] $Path   = ".", 
                        [string]   $Filter = "^(?!unversioned|normal|external)", 
                        [switch]   $NoFormat )
{
    # powershell chokes on "wc-status" and doesn't like two definitions of "item"
    [xml]$status = ( ( Invoke-Expression "svn status $( $Path -join ',' ) --xml" ) -replace "wc-status", "svnstatus" ) `
        -replace "item=", "itemstatus="

    $statusObjects = $status.status.target | Foreach-Object { $_.entry } | Where-Object { 
        $_.svnstatus.itemstatus -match $Filter 
    } | Foreach-Object {
        $_ | Select-Object @{ Name = "Status"; Expression = { $_.svnstatus.itemstatus } }, 
                           @{ Name = "Path";   Expression = { Join-Path ( Get-Location ) $_.path } }
    } | Sort-Object Status, Path

    if ( $NoFormat )
    {
        $statusObjects
    }
    else
    {
        $statusObjects | Format-Table -AutoSize
    }
}

function Get-SvnLog( [string] $Path = ".", 
                     [int]    $Revision, 
                     [int]    $Limit = -1, 
                     [switch] $Verbose, 
                     [switch] $NoFormat )
{
    $revisionString = ""
    $limitString = ""
    $verboseString = ""

    if ( $Revision )
    {
        $revisionString = "--revision $Revision"
    }

    if ( $Limit -ne -1 )
    {
        $limitString = "--limit $Limit"
    }

    if ( $Verbose )
    {
        $verboseString = "--verbose"
    }

    [xml]$log = Invoke-Expression "svn log $( $path -join ',' ) --xml $revisionString $limitString $verboseString"

    $logObjects = $log.log.logentry | Foreach-Object {
        $logEntry = $_

        $logEntry | Select-Object `
            @{ Name = "Revision"; Expression = { [int]$logEntry.revision } },
            @{ Name = "Author"; Expression = { $logEntry.author } },
            @{ Name = "Date"; 
               Expression = {
                   if ( $NoFormat )
                   {
                       [datetime]$logEntry.date
                   }
                   else
                   {
                       "{0:dd/MM/yyyy hh:mm:ss}" -f [datetime]$logEntry.date
                   }
               } },
            @{ Name = "Message"; Expression = { $logEntry.msg } } | 
        Foreach-Object {
            # add the changed path information if the $Verbose parameter has been specified
            if ( $Verbose )
            {
                $_ | Select-Object Revision, Author, Date, Message,
                    @{ Name = "ChangedPaths"; 
                       Expression = {
                           $paths = $logEntry.paths.path | Foreach-Object {
                               $_ | Select-Object `
                                   @{ Name = "Change"; 
                                      Expression = { 
                                          switch ( $_.action )
                                          {
                                              "A" { "added" }
                                              "D" { "deleted" }
                                              "M" { "modified" }
                                              "R" { "replaced" }
                                              default { $_.action }
                                          }
                                      } },
                                   @{ Name = "Path"; Expression = { $_."#text" } }
                           }

                           if ( $NoFormat )
                           {
                               $paths
                           }
                           else
                           {
                               ( $paths | Sort-Object Change | Format-Table -AutoSize | Out-String ).Trim()
                           }
                       } 
                     }
            }
            else
            {
                $_
            }
        }
    }

    if ( $NoFormat )
    {
        $logObjects
    }
    else
    {
        $logObjects | Format-List
    }
}

I have these aliased to svns and svnl, respectively. I talk about a few others here.

Jeff Hillman
Good call. I use the TFS Power Tool cmdlets just as often as anything I typed above, but not everyone has TFS. If you do have some sort of object model for your source control system of choice, mating it to Powershell is extremely good to learn.
Richard Berg
+2  A: 

It's not a script, but in general it's helpful to learn when you can short-cut parameters, both by name and position.

By name, PowerShell just needs enough to narrow it down to one. For example, gci -r works but gci -f might be either -filter or -force.

Values specified without a parameter label are applied positionally. So if you want to specify -filter you could either do this:

gci -r -fil *.cs

Or provide . positionally as -path so you can also specify -filter positionally:

gci -r . *.cs
dahlbyk