Monthly Archives: June 2009

Games: Advanced 5

In this event we have to pull some information out of the properties of some photos.  This information isn’t in the normal properties. We need to load the drawing classes to access the data.

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
#http://blogs.technet.com/jamesone/archive/2007/07/13/exploring-photographic-exif-data-using-powershell-of-course.aspx
function ConvertTo-Chars {
param ($bytedata)
    $str = ""
    for ($i=0; $i -le $bytedata.Length-1;$i++){
        $str = $str + [char]$bytedata[$i]
    }
    Return $str
}
cls
[reflection.assembly]::loadfile( "C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Drawing.dll") | out-null
"{0,-12} {1,-20} {2,-6} {3,-12}" -f  "Name", "Date Taken", "Make", "Model" 
Get-ChildItem *.jpg | foreach {
   $photo = New-Object -TypeName system.drawing.bitmap -ArgumentList $($_.FullName)
   $dts =  (ConvertTo-Chars $photo.GetPropertyItem(36867).value) -split " "
   $ds  = $dts[0] -split ":"
   $date = "{0}/{1}/{2} {3}" -f $($ds[2]), $($ds[1]), $($ds[0]), $($dts[1]) 
   $maker = ConvertTo-Chars $photo.GetPropertyItem(271).value
   $model = ConvertTo-Chars $photo.GetPropertyItem(272).value
   "{0,-12} {1,-20} {2,-6} {3,-12}" -f  $($_.Name), $date, $maker, $model 

}

 

Use –f to create a formatted string as a header.

Loop through the photos and create a bitmap object for the photo. The properties are held in a number of formats – they are explained in James’ blog that is commented in the beginning of the script. Luckily the ones we want are strings – but are held as byte arrays.

The camera maker and model are simply passed into the function that we use convert to a string.  The date we convert and then re-arrange from yyyy-mm-dd to dd/mm/yyyy format. We can then create a formatted script to display the data.

Technorati Tags: ,

Games: Beginner 5

This one involves setting some registry settings to increase the number of concurrent downloads.  I’m running Windows 7 and IE 8 which have already increased the limits from 2 to 6. Tobias has done a really good job on his expert commentary - http://blogs.technet.com/heyscriptingguy/archive/2009/06/18/hey-scripting-guy-event-5-solutions-from-expert-commentators-beginner-and-advanced-the-400-meter-race.aspx - so rather than repeat that I’m going to use this as an example of using transactions in PowerShell v2.

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
#Requires -version 2.0
#IE 8 increases limit to 6 from 2
#need to create keys
cls
cd "HKCU:\Software\Microsoft\Windows\CurrentVersion"
"Before"
Get-ItemProperty "Internet Settings"

Start-Transaction

New-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings" `  
 -Name MaxConnectionsPerServer -PropertyType DWORD -Value 10 -UseTransaction   | Out-Null
New-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings" `
 -Name MaxConnectionsPer1_0Server  -PropertyType DWORD -Value 10  -UseTransaction | Out-Null

"During"
Get-ItemProperty "Internet Settings" -UseTransaction

Read-Host "Continue"
Undo-Transaction

"After"
Get-ItemProperty "Internet Settings" 

cd \
cd c:

 

Use Requires to restrict to PowerShell v2

use the registry provider to navigate to the location of the settings and use get-itemproperty to display the values

We can then start our transaction. Make the changes and display the properties again.  Notice that we have to use the

-UseTransaction parameter to involve these cmdlets in the transaction.  A Read-Host is used to pause the script.  Check the values and we can seen that the properties have been added.  Continue the script by pressing any key (if you can find it)  and then the transaction will undo.  Display the properties again to show that the change has been undone.

Transactions are only available on the Registry provider at the moment.  Hopefully, they will be extended onto the other providers in the next version of PowerShell.

The incredible shrinking URL

Some urls on the web become a real pain to type because of their length.  Tinyurl, and other similar services, can be used to shrink the url to a much more manageable length.

Joe Pruitt has a PowerShell script to perform the shrinking – find it here http://devcentral.f5.com/weblogs/Joe/archive/2009/06/19/shrink-url-ndash-use-powershell-to-shrink-your-urls.aspx

Technorati Tags: ,

Games: Beginner 4

I did the expert commentary for this one – it can be read here http://blogs.technet.com/heyscriptingguy/archive/2009/06/17/hey-scripting-guy-event-4-solutions-from-expert-commentators-beginner-and-advanced-the-high-jump.aspx

Technorati Tags: ,

Games: Advanced 3

This one involves reading a text file, finding all the words that use a single vowel (may have multiple instances of that vowel e.g. look) and write them out to a text file.

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
## find the univowel words
## - 1 or more instances of the same vowel
## - all vowels the same
if (Test-Path univowel.txt){Remove-Item  univowel.txt}
Get-Content Wordlist_ADV3.txt | foreach {
    $y = 0
    $z = $_.ToCharArray()
    if ($z -contains "a") {$y++}
    if ($z -contains "e") {$y++}
    if ($z -contains "i") {$y++}
    if ($z -contains "o") {$y++}
    if ($z -contains "u") {$y++}
    if ($_ -eq "look"){"$_ $y"}
    if ($y -eq 1){Add-Content -Path univowel.txt -Value $($_)}
}

 

Delete the answer file if it exists.  Read the file & loop through the contents. Quick & dirty brute force approach for this one.  Convert the work to a character array and use contains to check for vowel membership – only 5 vowels so 5 if statements. Tried a switch but it counts each each instance so wrecks the result ie didn’t accept “look”.  For each hit increment the counter ($y).

At the end if $y = 1 it means we have only one vowel in the word so write it to the text file.

Not a task I need to do very often but it works.

Technorati Tags: ,

Kill the Messenger

I’ve mentioned before that I find the way that the latest incarnation of Messenger on Windows 7 keeps starting whenever I access any other Live product.  Finally got annoyed enough to make a kill messenger icon.

Create a shortcut on your desktop for the PowerShell exe and then change the target string (on Shortcut tab) to "%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe " -NoProfile -Nologo -Command  &"{Get-Process msnmsgr | Stop-Process}"

This starts up PowerShell without the profile and logo and immediately runs the command Get-Process msnmsgr | Stop-Process which terminates with extreme prejudice any instances of messenger.   On the same tab I also set the Run drop down to Minimized so I don’t get the full flash of PowerShell starting and shutting.

Messenger: you can start but you can’t run

Technorati Tags: ,

Virtual Conference

Don’t forget the TechNet virtual conference tomorrow (19th June).  There have been a lot of registrations for this – but we can squeeze a few more in at the back.

 

Games: Beginner 3

We start with a file and have to put the first paragraph into one file and the second into another file. 

001
002
003
004
005
006
007
008
009
010
$flag = $true
if (Test-Path "Shot Put A.txt"){Remove-Item "Shot Put A.txt"}
if (Test-Path "Shot Put B.txt"){Remove-Item "Shot Put B.txt"}
Get-Content "Shot Put.txt" | foreach {
    if ($_ -ne ""){
        if ($flag){Add-Content -Path "Shot Put A.txt" -Value $($_) }
        else {Add-Content -Path "Shot Put B.txt" -Value $($_)}
    }
    else {$flag = $false}
}

 

Create a flag (set true). Test for the existence of the output files and delete if present   Read the file and loop through.  We can identify the paragraph break as there is an empty line – when we get to that we change the value of the flag.  If the flag is true add the line to the first file otherwise add to the second file.

 

Technorati Tags: ,

Games: Advanced 2

This is playing in a spreadsheet.  Need to do some calculations and sorting

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
$header =  1   ## yes it does. 0 = no header
$asc  = 1      ## sort ascending
$desc = 2      ## sort descending

$xl = New-Object -comobject "Excel.Application"
$xl.visible = $true
$wkbk = $xl.WorkBooks.Open("C:\Scripts\Scripting Games 2009\Competitors pack\LongJump_Adv2.xls")
## $wkbk.workSheets | Format-Table Index, Name -AutoSize
$sheet = $wkbk.WorkSheets.Item(1)

$sheet.Cells.Item(1,10).FormulaLocal = "Ratio"

for ($i=2;$i -le 19; $i++){

## calculate score
$formula = "=max(e$i" + ":" + "g$i)"
$sheet.Cells.Item($i,8).FormulaLocal = $formula

## over or under achieving
$achieve = "=IF(H$i" + ">D" + $i + ',"Exceed",IF(H' + $i + "<D" + $i + ',"Under Perform","Achieve"))'
$sheet.Cells.Item($i,9).FormulaLocal = $achieve

## ratio over best
$ratio = "=(H" + $i + "/D" + $i + ")"
$sheet.Cells.Item($i,10).FormulaLocal = $ratio
}
## find the winner
$range = $sheet.UsedRange
$range1 = $xl.Range("H2")
$range.Sort($range1, $desc) | Out-Null
Write-Host "The winner is $($sheet.Cells.Item(2,1).FormulaLocal) `
             of $($sheet.Cells.Item(2,2).FormulaLocal) `
             with a jump of $($sheet.Cells.Item(2,8).Text)"

## sort the sheet by achievement
$range1 = $xl.Range("J2")
$range.Sort($range1, $desc) | Out-Null

 

Some constants are defined at the beginning and then we open the spreadsheet.  Add a header to an extra column we will be using (11) .  We can then loop through each row finding the maximum of the scores and putting it into the results column (17) In the same loop we can determine if they are exceeding their season best (21) and calculate a ratio (25)

A sort on the results column means we can pick off the winner (31) and then another sorts leaves the spreadsheet ordered by the comparison to the season best.  It can be saved like that if required.

Interesting mix of PowerShell and Excel but the challenges are in the Excel side and how to get that working in PowerShell rather than PowerShell itself.  One possibility would be to open the spreadsheet and create a csv file which would make some the work easier but its probably not worth the effort.

Technorati Tags: ,

Games: Beginner 2

In this one we need to use WMI to get some information about the Processor in our machine.  Main difficulty is finding which class. In PowerShell v2 I can get away with this

Get-WmiObject -List "*processor*"

whereas in v1 I need to use

Get-WmiObject -List | where{$_.Name -like "*processor*"}

In either case the Win32_Processor class looks to be the best choice.   This leads to

001
002
003
004
005
006
007
$machine = Get-WmiObject -Class Win32_Processor
"Speed"
$machine | Format-List MaxClockSpeed, L2CacheSize, L2CacheSpeed, L3CacheSize, L3CacheSpeed
"Strength"
$machine | Format-List NumberOfCores, NumberOfLogicalProcessors
"Agility"
$machine | Format-List AddressWidth

 

Get the WMI information once and then select the bits we want to meet the criteria

Get-WmiObject -Class Win32_Processor | Get-Member

will give a full list of the properties.

If you want to colour the output use write-host and pick off the properties individually

Technorati Tags: ,