Book arrived. :)

Finally I got my hand on PowerShell TFM. To be hones I haven’t expected it so soon. Hardly had time to read it though. Good news is that this week I will travel to work by bus/ subway and it means a LOT of time to spent on reading, one thing I can’t do if I (as usually) travel to work by car.

Second thing that SG are over. I mean in a write-scripts sense, because there is still a lot to come: experts articles, some articles by Scripting Guy Ed Wilson, and hopefully sooner than later – final standings. I’m looking forward to it, not that I expect some outcome (I probably ended in the middle of top ten, which is far more than I expected to), I’m just curious who won! 🙂

For me this whole SG stuff is very important learning experience. New things I thought I will never be able to learn. New ideas, new challenges I haven’t even though of before I had to in order to submit more than 2-stars script for advanced events. One script that I’m in a way proud of is the last one. It took me really a lot of time of banging head against desk in order to make all pieces to work well. It was a lot of effort for me to finally get everything in correct place, working both with ISE and standard console. But there it is:

        Simple GUI app to move files away from desktop.
        Tired of looking at all those files at your desktop? This script is here to help you!
        Not only will it move all files to different location that you choose.
        It will also create a link for you on your desktop!
        With no parameters given it will move everything but links.
        If you want to keep some other types - let the script know, simply add -Exclude extensions.
        Using registry to pass arguments between windows (yes, I'm sure there is easier way, simply could not find it...)
        Using windows.forms.messagebox as a simple UI.
        Clear-Destkop.ps1 -Path C:temp -Exclude mp3, jpg
        Will move everything to c:temp and will not move any lnk, mp3 and jpg files.
        Clear-Desktop.ps1 -Exclude txt
        Moves everything except .lnk and .txt to location that you select using GUI
    .Parameter Path
        Define path to folder that will be used to store files.
    .Parameter Exclude
        List of extensions that will be excluded from move operation
    [parameter(HelpMessage='Provide a path to file(s)/ folder(s) that will be used to store files moved away from desktop')]            
    [parameter(HelpMessage='Provide a list of extensions that will be excluded from operation')]            
 if ([Threading.Thread]::CurrentThread.ApartmentState -eq 'STA') {            
  $isSTA = $true            
 } else {            
  $isSTA = $false            
 if (!$isSTA) {            
  Write-Host "Need STA mode or ISE to launch this script"            
  Throw "Use powershell.exe with -STA parameter or Ise to launch this script"            
 if (!(Get-Module WPK)) {            
  if (!(Get-Module WPK -ListAvailable)) {            
   Write-Host "Need WPK module (comes with PowerShellPack) to run"            
   Throw "Install PowerShell Pack first"            
  } else {            
   Import-Module WPK            
    # Just in case - fix Excludes first.            
    $RegPath = 'HKCU:SoftwareScriptingGuys2010ScriptingGames'            
    $__Exclude = @('.lnk')            
    foreach ($ext in @($Exclude)) {            
        $__Exclude += $($ext) -replace '^.*.|^(.*)$', '.$1'            
    # Get rid of all duplicates...            
    $__Exclude = @($__Exclude | Sort-Object -Unique)            
    if (Get-ItemProperty -Path $RegPath -Name 'Excludes' -ErrorAction 'SilentlyContinue') {            
        Set-ItemProperty -Path $RegPath -Name 'Excludes' -Value $__Exclude            
    } else {            
        New-ItemProperty -Path $RegPath -Name 'Excludes' -Value $__Exclude -PropertyType multistring            
    # And save a dest path in registry            
    Set-ItemProperty -Path $RegPath -Name 'Evt10Dest' -Value $Path            
    # define some general-purpose functions (again - in global scope)            
    function Global:Show-UIDialog {            
        param([string]$MenuMessage, $MenuTitle)            
        [Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | Out-Null            
        $Answer = [Windows.Forms.MessageBox]::Show($MenuMessage,$MenuTitle,"YesNo","Question")            
        return $Answer.ToString()            
    Function Global:Show-UIMessage {            
        param([string]$Message, [string]$Title = 'Update-USBContents - Information')            
            [Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | Out-Null            
            [Windows.Forms.MessageBox]::Show($Message,$Title,"OK","Information") | Out-Null                 
    New-Window -Name "WPK" -Title "WPK Snippets" -Width 400 -Height 220 -Show -FontSize 14 -FontFamily Tahoma {            
        New-Grid -Rows 120, 56* {            
            $Text = "This program will clean up your desktop!"            
            $Text += "`nIf you like the idea - select path that you want to move your files and click YES!"            
            $Text += "`nIf not - just close the window. And suffer! :P"            
            $Text += "`nClick 'Folder' to select destination folder or manually enter path."            
            New-TextBlock -TextWrapping Wrap -Text $Text            
            New-Grid -Row 1 -Rows 28,28 -Columns 75,300* {            
                New-TextBlock -Text "Folder Path:" -Row 0 -Column 0 -Margin 3            
                New-TextBox -Name txtUserName -Row 0 -Column 1 -Margin 3 -On_Loaded {            
                    $RegPath = 'HKCU:SoftwareScriptingGuys2010ScriptingGames'            
                    if ($StartValue = $(Get-ItemProperty -Path $RegPath -Name 'Evt10Dest').Evt10Dest) {            
                        $this.Text = $StartValue            
                New-Button -Content "Folder" -Name btnFolder -Row 1 -Column 0 -Margin 3 -On_Click {            
     [Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | Out-Null            
                    $obj = New-FolderBrowserDialog -RootFolder "MyComputer"            
                    $txtUserName = $Window | Get-ChildControl txtUserName            
                    $txtUserName.Text = $obj.SelectedPath             
                New-Button -Content "YES!" -Name btnGO -FontWeight Bold -Row 1 -Column 1 -Margin 3 -On_Click  {            
                    $txtUserName = $Window | Get-ChildControl txtUserName            
                    $Global:__Dest = $txtUserName.Text            
                    # Wy not use registry for that.... ;)            
                    # if even GLOBALS are missing in Script-Block? :(            
                    $RegPath = 'HKCU:SoftwareScriptingGuys2010ScriptingGames'            
                    if (!(Test-Path $RegPath )) {            
                        mkdir -Force $RegPath            
                    Set-ItemProperty -Path $RegPath -Name 'Evt10Dest' -Value $__Dest            
                    New-Window -Name "FileMove" -DataBinding @{"Title" = "LastProgress.Activity"} -Width 600 -Height 200 -Show {            
                        New-Grid -Rows 100,100 {            
                            New-TextBlock -TextWrapping Wrap -Name "CopyFileName" -FontSize 16 -DataBinding @{"Text" = "LastProgress.StatusDescription"}            
                            New-ProgressBar -Row 1 -DataBinding @{"Value" = "LastProgress.PercentComplete"}            
                    } -DataContext {            
                        Get-PowerShellDataSource -Script {            
                            $Dest = (Get-ItemProperty -Path 'HKCU:SoftwareScriptingGuys2010ScriptingGames' -Name 'Evt10Dest').Evt10Dest            
                            if (!(Test-Path $Dest)) {            
                                # No folder! No folder! Create one to move on!            
                                mkdir -Force $Dest            
                            $Exclude = @($(Get-ItemProperty -Path 'HKCU:SoftwareScriptingGuys2010ScriptingGames' -Name 'Excludes').Excludes)            
                            $Desktop = [environment]::GetFolderPath('Desktop')            
                            $counter = 0            
                            $j = 1            
                            $TotalCount = Get-ChildItem -Recurse -Force $Desktop | ? { ! $_.PSIsContainter -and ($Exclude -notcontains $_.extension) } | Measure-Object | Select-Object -ExpandProperty count            
                            if ($TotalCount -gt 100) {            
                                $minFileCounter = $TotalCount/100            
                                $fix = 0            
                            } elseif ($TotalCount -gt 0) {            
                                [int32]$fix = 100/$TotalCount -1            
                                $minFileCounter = -1            
                            } else {            
                                trow "No files to process"            
                            Get-ChildItem -Force -Recurse -Path $desktop |  ? { (! $_.PSIsContainter) -and ($Exclude -notcontains $_.extension) } | ForEach-Object {            
                                Try {            
                                    $sourcefile = $_.FullName            
                                    $destfile = $sourcefile.replace($Desktop, $Dest)            
                                    $destfileparent = $(Split-Path $destfile)            
                                    if (!(Test-Path $destfileparent)) { mkdir -Force $destfileparent}            
                                    Move-Item -Force -Path $sourcefile -Destination $destfileparent            
                  if ($counter -gt $j*$minFileCounter) {            
                                     $j += $fix            
                 } Catch {            
                  Show-UIMessage "ERROR: $_,Exception.Message"            
                 Write-Progress "Progress: $j %" "Moving file: $sourcefile to $Destfileparent ..."  -PercentComplete $j            
                            # Get rid off empty folders...            
                            $Folders = @()            
                            Get-ChildItem -Force -Recurse $Desktop | Where-Object { $_.PSIsContainer }  | ForEach-Object { $Folders += $_.FullName }            
                            $Folders = $Folders | Sort-Object -Descending -Unique            
                            Foreach ($folder in $folders) {            
                                if (!(Get-ChildItem -Force $folder)) {            
                                    # empty...            
                                    Remove-Item $folder -Force            
                            # And last but not least - create shortcut... :)            
                            $date = Get-Date -UFormat '%Y_%m_%d_%H_%M'            
                            $wsh = New-Object -ComObject Wscript.Shell            
                            $link = $wsh.CreateShortcut("$DesktopMoved Files_$date.lnk")            
                            $link.TargetPath = $Dest            
                            $link.WorkingDirectory = $Dest            
                            $link.Description = "Automaticaly created by Clear-Desktop"            
                Write-Progress "Done!" "Close this window!" -PercentComplete 100            


Alll sytnax works thanks to tweaked a bit ‘Copy-ColorizedHTML from ISEPack. You can find script also on poshcode SG site, here: click

Blog_17_05_2010_1And that how it works: see? I’ve used piece of code here, and piece of code there to start with. But to make it work all together – man, that was a real challenge! And you know what? When I decided to let my wife know about SG and I’ve shown her standings after Wednesday I was sure she will be kind of angry: that I’ve wasted time I hardly have on some ‘games’. Well, it was opposite. She was… touched in a way, that I was able to get that high. She’s proud of me and that makes whole thing even better. But to add some bitter to this honey pot – you should read blog from (most likely) winner of whole SG contest this year. Some good point there about judging mainly that I have to agree with, seen here. After all – how can one care much about ‘stars’ if those stars are meaningless without feedback?

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s