Tuesday, June 17, 2008

Exploration of .NET through 'Powertab' interrogation continues. I still don't know how to benefit from 'Powertab' just yet...I would like to know is Powershell can call these Properties below.

.GetMembers() | %{$_.Name}

Querying .NET in Powershell. The ability to use the vast repertoire of .NET in Powershell is impressive. More difficult of late has been how to find .NET functions and call arguments. I was stuck reading the 3.5 Framework docs doing clunky stuff like this:

$webclient = New-Object System.Net.WebClient
$a = ($webclient | gm) | % {$_.Name}
$b = ( $a | % {$WebClient.$_} )
$c = ( $b | Select Name , OverloadDefinitions )
write $c

But then I installed 'PowerTab' and can tab my way to knowledge with the '.findmember' property. (This works without 'PowerTab' but is nowhere near as easy and complete.)


PS [RMFMEDIA] >[System.Net.WebClient].FindMembers | ft -auto -wrap

WARNING: 4 columns do not fit into the display and were removed.

MemberType OverloadDefinitions
---------- -------------------
Method {System.Reflection.MemberInfo[] FindMembers(MemberTypes memberType, BindingFlags bindingAttr, MemberFilter filter, Object filterCriteria)}

Wednesday, June 11, 2008

Selected 'Exif' statistics script is below. There are a number of ways I can improve it: Stream output, skip csv file creation (as an interim step) read list with arrays and parameters, using regex expressions to best effect. Still, quite a few lessons learned with this and the output can help check for errors. The issue is that 'exif' (Cygwin, GNU output) will sometimes skip fields. I am not checking for that or other error conditions in general but the 'Counts' need to sync up at least. That being said, 'measure-object' cmdlet gives me some easy 'meta-file' (exif) stats about my JPGs. Output looks as below. I am still not solving the problem that I do not know how to obtain select "meta-file" information from Powershell.

Count : 214
Average :
Sum :
Maximum :
Minimum :
Property : Exif_Tag

Count : 214
Average : 7.07102803738318
Sum :
Maximum : 13
Minimum : 3.5
Property : FNumber

Count : 214
Average : 58.0140186915888
Sum :
Maximum : 82
Minimum : 27
Property : Focal_Length

## Get-exif-stats.ps1
$exif_index = gci *.jpg | %{exif ($_.Name)}
$c = $exif_index | Select-String -pattern "EXIF tag" , FNumber , "Focal Length In 35mm"
$c1 = ("$c").Split( ) | Select-String -pattern JPG , f/ , mm
$c2 = (("$c1").Replace( "'" , "")).Split()
$c3 = (("$c2").Replace( " |f/" , ",")).Split()
$c4 = (("$c3").Replace( " 35mm|" , ",")).Split()

if ((gci PhotoData.csv).Exists -eq "True") {mv PhotoData.csv PhotoData.csv.old -force}

"Exif_Tag,FNumber,Focal_Length" | out-file PhotoData.csv
$c4 | out-file -append PhotoData.csv
$PhotoData = import-csv -path PhotoData.csv

$FileName = ( $PhotoData | Measure-Object -Property Exif_Tag )
$FNumber = ( $PhotoData | Measure-Object -Property FNumber -average -maximum -minimum )
$Focal_Length = ( $PhotoData | Measure-Object -Property Focal_Length -average -maximum -minimum )

echo $FileName
echo $FNumber
echo $Focal_Length

Monday, June 9, 2008

Some progress tonight parsing 'exif' output with .Split and .Replace operators. Lee Holmes book is excellent on the use of comparison operators and text parsing. The script below takes text like this:

EXIF tags in 'P1050027.JPG' ('Intel' byte order):
FNumber |f/3.7
Focal Length In 35mm|71

and turns it into CSV delimited fields like this:


## ParseExif.ps1
$exif_index = gci *.jpg | %{exif ($_.Name)}

$c = $exif_index | Select-String -pattern "EXIF tag" , FNumber , "Focal Length In 35mm"
$c1 = ("$c").Split( ) | Select-String -pattern JPG , f/ , mm
$c2 = (("$c1").Replace( "'" , "")).Split()

$c3 = (("$c2").Replace( " |" , ",")).Split()

$c4 = (("$c3").Replace( " 35mm|" , ",")).Split()

Sunday, June 8, 2008

The 'exif' program spits out an array of tags which I thought were consistently 56 lines (see below). (They are not of course.) So I attempted to query the 0 (filename) and the 20 (FNumber) per every group of 56 as if the output was an artificial array always 56 lines in length.

e.g. I am attempting to index an array of data by line number. This wasn't useful, but as an exercise in use of PS range operators and while construct. I am looking for some method to use PS to create objects from foreign data constructs. I think this may be approached more effectively else wise.

$exif_index = gci *.jpg | %{exif ($_.Name)}
$eil = $exif_index.length
$i = $eil

while ($i -gt 56)

$file_name = ($eil - ($i - 0))
$FNumber = ($eil - ($i - 20))
## 56 is size of array
$i = ($i - 56)

Something like this results:
EXIF tags in 'P1050027.JPG' ('Intel' byte order):
FNumber |f/3.7
EXIF tags in 'P1050028.JPG' ('Intel' byte order):
FNumber |f/3.7
EXIF tags in 'P1050029.JPG' ('Intel' byte order):
FNumber |f/4.1
EXIF tags in 'P1050030.JPG' ('Intel' byte order):
FNumber |f/4.1

[full exif dump]

26# $exif_index | more
EXIF tags in 'P1050027.JPG' ('Intel' byte order):
Tag |Value
Manufacturer |Panasonic
Model |DMC-TZ1
Orientation |top - left
x-Resolution |72.00
y-Resolution |72.00
Resolution Unit |Inch
Software |Ver.1.0
Date and Time |2008:06:04 09:54:14
YCbCr Positioning |co-sited
Compression |JPEG compression
Orientation |top - left
x-Resolution |72.00
y-Resolution |72.00
Resolution Unit |Inch
YCbCr Positioning |co-sited
Exposure Time |1/800 sec.
FNumber |f/3.7

Saturday, June 7, 2008

All I really want is a 'Get-exif' cmdlet in Powershell so I can compare specs in 'list' below for photos I have taken. I don't want to query .NET or load an assembly or set up an array. !!! Read four or five blogs on the matter. Read Lee Holmes Cookbook. Cygwin's exif with CMD.exe trumps anything Powershell I could come up with. A stupid wasted afternoon and morning.

more list
Exposure Time

Focal Length

Exposure Mode

(one line in cmd.exe)
for /f %i in ('dir /b *.jpg') do exif %i | Findstr -g:list && pause

(I need PS to do more than this..)

$exif_index = gci *.jpg | %{exif ($_.Name)}

Sunday, June 1, 2008

Okay...This uses 'Ping-Host' from PSCX PSSnapin. My function still doesn't do what I want it to do but..more promising. Give function first three octets (and hard code range - 1..254) , Bytes, Wait, Count (which only works as below with count of one right now...) Then Prints (only) Hosts UP, IP Address, AverageTime, MinimumTime, MaximumTime, Loss as so....Stats are misleading since I think (?) it is the ave, min, max for each separate run? )....Will fix this...and TTL...Man, Powergui is helpful. So are the NetCmdlets. Anyway, 'ping-host' is faster..than accessing the .NET ping(send) functionality from the post before this. My programming logic is still not standard. I should be using params and arrays as Holmes and Payette specify

.\CheckClassC_NC_function.ps1 209.85.173. 8000 1 20

Host UP,,228,228,228,0
Host UP,,42,42,42,0
Host UP,mh-in-f17.google.com,38,38,38,0
Host UP,mh-in-f18.google.com,41,41,41,0
Host UP,mh-in-f19.google.com,37,37,37,0
Host UP,mh-in-f32.google.com,42,42,42,0

function CheckHostClassC_function
## ($Subnet,$BufferSize,$Count,$Timeout,$TTL)
begin {$ping =(Ping-Host -Quiet -HostName $Subnet$_
-BufferSize $BufferSize -Count $Count -Timeout $Timeout );
$pingtrue =($ping.Received)
$host_ = ($ping.Host) ;
$AverageTime_ = ($ping.AverageTime) ;
$MinimumTime_ = ($ping.MinimumTime) ;
$MaximumTime_ = ($ping.MaximumTime) ;
$Loss_ = ($ping.Loss) ;

process {if ($pingtrue -eq "1")
{"Host UP"+","+"$host_"+","+"$AverageTime_"+","+

sv Subnet $Args[0]
sv BufferSize $Args[1]
sv Count $Args[2]
sv Timeout $Args[3]
## sv TTL $Args[4]

1..254 | %{CheckHostClassC_function}