Liste der installierten Programme per Powershell auslesen

imageNach langer Pause hier wiedermal ein nützlicher “Powershell-Einzeiler”

Habe einen neuen Laptop bekommen, diesen natürlich neu aufgesetzt, und jetzt benötige ich eine Liste der Programm vom alten Laptop, um diese durchzusehen, zu filtern, und dann natürlich einige der Programme auch am neuen Laptop wieder zu installieren.

Screenshots aus der Systemsteuerung “Programme und Funktionen” sind etwas mühsam, und auch einem Geek nicht würdig Zwinkerndes Smiley

Daher mal schnell ein Powershell Script gebaut, wie es sich gehört, natürlich als Einzeiler:

1 get-wmiobject -class "Win32_Product" -namespace "root\CIMV2" -computername "." | format-list Vendor, Name, Caption, Description, Version, InstallDate, HelpLink

Ergebnis:

image

Oder, falls wir die Liste in Excel noch bearbeiten oder filtern möchten, senden wir das ganze gleich direkt in ein CSV File:

1 get-wmiobject -class "Win32_Product" -namespace "root\CIMV2" -computername "." | select-object Vendor, Name, Version, InstallDate, HelpLink | Export-Csv -path c:\installierte_programme.csv -UseCulture

image

Which is the Fastest Browser?

JavaScript and HTML5 benchmarks such as IEFishtank or Androids are nice enough but less significant for daily use. They are definitely interesting for the “web of the future” but currently the Internet isn’t primarily used for complex HTML5 games and virtual aquariums but to pull up normal websites such as Google, Facebook, YouTube, CNN etc.

I wanted to carry out a practical speed test of browsers — specifically the loading time of each individual browser from the startup of the browser (mouse click) until the site is fully loaded and rendered. This test was quite extensive and time-consuming and further below I will explain the methodology used but here are the results: 

Browser

Rank ø

Loading time ø

1. Internet Explorer 9 64Bit RTM 2,00 1,30
2. Internet Explorer 9 32Bit RTM 2,63 1,54
3. Google Chrome 10.0.648.133 3,00 2,05
4. Firefox 4 RC 3,38 1,78
5. Opera 11.01 4,50 2,78
6. Safari 5.04 5,38 3,50

The following websites were tested:

  • Facebook
  • Amazon.de
  • Youtube.com
  • CNN.com
  • NYTimes.com
  • Wikipedia.org

Each site was individually loaded with each browser and the time from the first mouse click until the site was fully loaded and displayed was measured.

For each site a rank was awarded—here you see the average of the loading time (in red) and the average rank in blue. One can argue whether Chrome or Firefox are on ranks 3 or 4, depending on whether you consider the average load time or the average rank of the individual tests more significant.
 Mean rank and mean loading time (smaller is better.)
Mean rank and mean loading time (smaller is better.)

Conclusion: Internet Explorer 9 RTM isn’t only impressively speedy at HTML5 and JavaScript benchmarks but is also the fastest browser when tested in practical use scenario tests.


Methodology

The basic idea was to call up typical websites with current browsers and measure the total loading time from the first click to the fully loaded and displayed site. 
Originally I wanted to automate the tests and the tool HttpWatch was recommended to me. By further examination I noticed that this tool wasn’t appropriate for this test as it only measured the loading time of the markup and not how long the browser takes to start up, load the markup and render the complete page.

I had to measure the time manually. Naturally I didn’t use a stopwatch since the time differences between measurements were only  hundredths of a second. I wrote a Power Shell script and set it loose against the six websites with the six various browsers. Every seven seconds (15 seconds in the second test run) a website was pulled up with a browser. At the same time Camtasia Studio was used to capture a screen video.
image_thumb9
In order to later see the click in the timeline of the video editing program Camtasia Studio, a peep tone was played back immediately before triggering the browser. That way I only had to look in the video for the point where the peep tone is, and measure the time from there to where the page has finished loading and rendering. This is pretty straightforward – but I had to repeat this 48 times, which made the whole thing pretty time consuming.
The process is quite precise – at 15 frames per second the resulting duration is precise to fifteen hundredth of a second, with the Video analyzed frame by frame.
image28

For who wants to bother checking my results, you can find the whole screencast with all measurements on Youtube:

Measuring Browser Speed

Welcher ist der schnellste Browser?

JavaScript und HTML5 Benchmarks wie IEFishtank oder Asteroids sind ja recht nett, aber für den Alltag wenig aussagekräftig. Sie sind sicher interessant für das “Web der Zukunft”, aber momentan wird das Internet nicht primär für aufwändige HTML5 Games und virtuelle Aquarien verwendet, sondern um normale Webseiten aufzurufen wie Google, Facebook, YouTube, CNN etc.

Ich wollte daher einen praxisnahen Browsertest durchführen und konkret die Ladezeit der einzelnen Browser testen, und zwar vom Starten des Browsers (Mausklick) bis die Seite fertig geladen ist. Dieser Test war ziemlich aufwändig und weiter unten werde ich die Methoden näher erläutern, aber hier zunächst die Ergebnisse:

Browser

Rang ø

Ladezeit ø

1. Internet Explorer 9 64Bit RTM 2,00 1,30
2. Internet Explorer 9 32Bit RTM 2,63 1,54
3. Google Chrome 10.0.648.133 3,00 2,05
4. Firefox 4 RC 3,38 1,78
5. Opera 11.01 4,50 2,78
6. Safari 5.04 5,38 3,50

Getestet wurden die Webseiten

  • Facebook
  • Amazon.de
  • Youtube.com
  • CNN.com
  • NYTimes.com
  • Wikipedia.org

Jede Seite wurde in jedem Browser geladen und die Zeit vom Mausklick bis zur fertig geladenen und dargestellten Seite danach gemessen.

Für jede Seite wurde auch ein Rang ermittelt, hier sieht man den Mittelwert der Ladezeit (rot) und den mittleren Rang (blau). So könnte man in der Gesamtwertung darüber diskutieren ob Chrome oder Firefox auf Platz 3 oder 4 liegen, je nachdem ob man die durchschnittliche Ladezeit heranzieht oder den durchschnittlichen Rang bei den einzelnen Tests.
Internet Explorer 9RTM im Vergleich mit Chrome, Firefox, Opera und Safari
Mittlerer Rang und Mittlere Ladezeit (kleiner ist besser).

Fazit: Internet Explorer 9 RTM kann nicht nur bei HTML5 und JavaScript Benchmarks mit seiner Geschwindigkeit überzeugen, sondern auch im Praxistest ist er der schnellste Browser.


Methodik

Die Grundidee war, typische Webseiten mit allen aktuellen Browsern aufzurufen und die gesamte Ladezeit zu messen, vom Klick bis zur fertig dargestellten Seite.
Ursprünglich wollte ich die Testreihe möglichst automatisieren und mir wurde dafür ein Tool namens HttpWatch empfohlen. Bei genauerer Betrachtung war dieses Tool aber ungeeignet, da es nur die Ladezeit des Markups misst, und nicht wie lange der Browser zum starten braucht und wie lange er zum Rendern der Seite braucht.
Ich musste also die Zeiten händisch messen. Natürlich würde das mit einer Stoppuhr nicht funktionieren, da die Unterschiede im Hundertstelbereich liegen. Ich erstellte daher ein Power Shell Skript um die  6 verschiedenen Browser auf 6 verschiedene Webseiten loszulassen. Alle 8 Sekunden (im zweiten Test 15 Sekunden) wurde ein Browser mit einer Webseite aufgerufen, gleichzeitig wurde das ganze mit Camtasia Studio als Screen-Video aufgezeichnet.
Browser Ladezeiten in Camtasia Studio gemessenUm den Klick in der Timeline des Schnittprogramms Camtasia Studio später auch visuell erkennen zu können, wurde unmittelbar vor dem Aufruf des Browsers ein Biep-Ton ausgelöst. So musste ich nachher nur im Video die Stelle mit dem Biep suchen und die Zeit von dort bis zu dem Punkt wo die Seite fertig geladen wurde messen. Dies ist eigentlich recht einfach – das ganze musste ich aber 48 mal wiederholen, was die Sache etwas zeitaufwändig machte.
Der Prozess ist ziemlich genau – bei 15 Frames pro Sekunde sind die Ergebnisse dementsprechend auf fünfzehn Hundertstelsekunden genau, wenn man das Video framegenau auswertet.

Messen der Browser Ladezeiten in der Timeline von Camtasia Studio

Wer sich gerne die Mühe machen will, in meinem Video die Zeiten nachzumessen, der findet hier den gesamten Screencast mit allen Messungen auf Youtube:

Browser Geschwindigkeiten gemessen

Die Detailergebnisse meiner Messungen:

Browser Webseite Ergebnis Rang
Chrome Facebook 1,24 4
Firefox 4 RC Facebook 1,14 3
Safari Facebook 2,00 5
Opera Facebook 2,02 6
IE9 32Bit Facebook 1,04 1
IE9 64Bit Facebook 1,04 1
Chrome Amazon 1,19 3
Firefox 4 RC Amazon 1,24 5
Safari Amazon 2,19 6
Opera Amazon 1,14 1
IE9 32Bit Amazon 1,16 2
IE9 64Bit Amazon 1,22 4
Chrome Youtube 0,27 1
Firefox 4 RC Youtube 1,10 3
Safari Youtube 2,02 6
Opera Youtube 1,29 5
IE9 32Bit Youtube 1,21 4
IE9 64Bit Youtube 1,07 2
Chrome CNN 2,15 2
Firefox 4 RC CNN 2,17 4
Safari CNN 3,28 6
Opera CNN 2,16 3
IE9 32Bit CNN 2,26 5
IE9 64Bit CNN 1,18 1
Chrome New York Times 5,04 6
Firefox 4 RC New York Times 2,19 3
Safari New York Times 4,19 5
Opera New York Times 4,15 4
IE9 32Bit New York Times 1,24 1
IE9 64Bit New York Times 1,25 2
Chrome CNN (2) 3,02 1
Firefox 4 RC CNN (2) 3,12 2
Safari CNN (2) 4,04 4
Opera CNN (2) 4,10 6
IE9 32Bit CNN (2) 4,06 5
IE9 64Bit CNN (2) 3,23 3
Chrome New York Times (2) 3,19 4
Firefox 4 RC New York Times (2) 2,20 3
Safari New York Times (2) 9,04 6
Opera New York Times (2) 6,11 5
IE9 32Bit New York Times (2) 1,17 1
IE9 64Bit New York Times (2) 1,24 2
Chrome Wikipedia 0,26 3
Firefox 4 RC Wikipedia 1,06 4
Safari Wikipedia 1,23 5
Opera Wikipedia 1,25 6
IE9 32Bit Wikipedia 0,21 2
IE9 64Bit Wikipedia 0,13 1

Insgesamt hatte ich zwei Testläufe, da ich im ersten Testlauf das Testfenster mit 7 Sekunden zu knapp bemessen hatte, und vor allem für die Seiten, die besonders lange zum Laden brauchten, (wie New York Times und CNN) einen zweiten Messwert haben wollte, außerdem ergänzte ich im zweiten Testlauf noch Wikipedia – die Seite im Test die übrigens am schnellsten geladen wurde.

Internet Explorer 9 konnte im Test Wikipedia in nur 13 Hundertstelsekunden laden!

Wer das ganze gerne selber ausprobieren möchte, muss sich alle genannten Browser installieren und folgendes Power Shell Skript ausführen:

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
037
038
039
040
041
042
043
044
045
046

# List of browsers
$strBrowsers =
 @(`
               
"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe",
 `
               
"C:\Program Files (x86)\Mozilla Firefox\firefox.exe",
 `
               
"C:\Program Files (x86)\Safari\Safari.exe",
 `
               
"C:\Program Files (x86)\Opera\opera.exe",
 `
               
"C:\Program Files (x86)\Internet Explorer\iexplore.exe",
 `
               
"C:\Program Files\Internet Explorer\iexplore.exe"
`
                );


# List of websites
$strWebsites =
 @(`
               
"http://www.facebook.com/windowsdeutsch?sk=wall",
 `
               
"http://www.amazon.de",
 `
               
"http://www.youtube.com",
 `
               
"http://www.cnn.com",
 `
               
"http://www.nytimes.com/",
 `
               
"http://de.wikipedia.org"
`
                );


CloseAllBrowsers

foreach ($objWebsite in $strWebsites
) {
   
foreach ($objItem in $strBrowsers
) {
       
[console]::beep(415, 100
)
       
Start-Process -FilePath $objItem
 `
                     
-ArgumentList $objWebsite
 `
                     
-WindowStyle Maximized
        Start-Sleep -s 1
        $objItem = Split-Path $objItem -Leaf
        $objItem = $objItem.
ToLower()
       
$objItem = $objItem -replace(".exe",""
)
       
Get-Process $objItem | foreach {$_.
CloseMainWindow()}
       
Start-Sleep -s 1
    }
}


function CloseAllBrowsers
{
   
foreach ($objItem in $strBrowsers
) {
       
$objItem = Split-Path $objItem -Leaf
        $objItem = $objItem.
ToLower()
       
$objItem = $objItem -replace(".exe",""
)
       
Get-Process $objItem | foreach {$_.CloseMainWindow()}
    }
}

Ich bin mir bewusst, dass man für aussagekräftigere Ergebnisse mehrere Durchläufe machen müsste, und vielleicht noch ein paar Webseiten mehr in den Test einbeziehen sollte, aber da die Messungen ja manuell erfolgen, habe ich dafür die Zeit nicht. Aber irgendwie denke ich, dass das das Ergebnis nicht stark verändern würde Zwinkerndes Smiley

Per Powershell Skript die Priorität von Prozessen verändern

Vor zwei Jahren habe ich ein WSH Skript vorgestellt, mit dem man die Priorität von Prozessen verändert.

Das Skript hat selbst in seiner Kurzform 18 Zeilen, wobei man es sicher noch kürzen könnte.

War ich früher ein großer Fan von WSH gilt meine Vorliebe heute Powershell und den wunderbaren Powershell Einzeilern die so manchem Admin das Leben erleichtern.

So läßt sich das ganze Skript in Powershell in einer Zeile zusammenfassen:

gps <ProcessName>| % { $_.PriorityClass = "High" }

Dabei ist gps die Kurzform von get-process und % die Kurzform von foreach.

Also man könnte es auch so schreiben:

Get-Process <ProcessName>| foreach { $_.PriorityClass = "High" }

Am Beispiel von Internet Explorer würde das also so aussehen:

gps iexplore | % { $_.PriorityClass = "High" }

Falls man sich die Prozess Priority Klassen nicht merken kann, einfach einen ungültigen Parameter angeben, und Powershell liefert in der Fehlermeldung die Liste der richtigen Parameter:

image

Mögliche Enumerationswerte sind "Normal, Idle, High, RealTime, BelowNormal, AboveNormal"

Windows Product Key per Powershell auslesen

GetProductKey.ps1

$map="BCDFGHJKMPQRTVWXY2346789"
$value = (get-itemproperty "HKLM:\\SOFTWARE\Microsoft\Windows NT\CurrentVersion"
).digitalproductid[0x34..0x42] 
$ProductKey = "" 
for ($i = 24; $i -ge 0; $i--
) {
  $r =
0
  for ($j = 14; $j -ge 0; $j--
) {
    $r = ($r * 256) -bxor $value[$j
]
    $value[$j] = [math]::Floor([double]($r/
24))
    $r = $r %
24
  }
  $ProductKey = $map[$r] +
$ProductKey
  if (($i % 5) -eq 0 -and $i -ne
0) {
    $ProductKey = "-" +
$ProductKey
  }
}
echo "Product Key:" $ProductKey

Powershell Einzeiler: Leistungsindex auslesen

 

get-wmiobject win32_winsat | select *score


PowerShell v2 Youtube Video Downloader

PowerShell v2 Youtube Video DownloaderThis script requires PowerShell v2 in it’s final version (as included in Windows 7 RTM).

This script will download any Youtube video in it’s best available quality as an MP4 file.

Syntax: GetYouTube Video-ID

Example: GetYouTube irp8CNj9qBI

Of course, one can also send a list of video ids to the script via a prepared text file, like so:

foreach ($video in get-content list.txt) { getyoutube.ps1 $video  } 

Here is the script GetYouTube.ps1:

Import-Module bitstransfer
$ErrorActionPreference = "SilentlyContinue"
$v=$args[0]
#$v="irp8CNj9qBI"
#Grab Youtube Page
$s=(New-Object System.Net.WebClient).DownloadString("http://www.youtube.com/watch?v=" + $v)
#extract token
$t=$s | % {$_.substring($_.IndexOf("`"t`": `"")+6,44)}
#extract title
$r="<title\b[^>]*>YouTube - (.*?)</title>" ; $f = $s | ?{ $_ -match $r } |  %{ $_ -match $r | out-null ; $matches[1] }
#Try downloading 720p version of video
$u = "http://www.youtube.com/get_video?fmt=22&video_id=" + $v + "&t=" + $t
$o = $Env:Userprofile + "\Videos\" + $f + "(HQ).mp4"
Start-BitsTransfer –source $u -destination $o
#Try downloading regular mp4 version of video, if HQ version failed
if (!$?) {
$u = "http://www.youtube.com/get_video?fmt=18&video_id=" + $v + "&t=" + $t
$o = $Env:Userprofile + "\Videos\" + $f + ".mp4"
Start-BitsTransfer –source $u -destination $o
}

Powershell Einzeiler: Anzahl der Prozesse, Programme oder Fenster

get-process
gibt mir eine Liste aller Prozesse

([Object[]](Get-Process)).Count
gibt mir die Anzahl aller Prozesse

Eine Liste aller Fenster – d.h. Prozesse die auch über ein Fenster verfügen bekomme ich so:

get-process | where {$_.mainWindowTitle} | format-table id, name, mainwindowtitle -autosize

Und so bekomme die Anzahl der offenen Fenster:

([Object[]](Get-Process  | where {$_.mainWindowTitle})).Count

Powershell Einzeiler: Einzelnen, internen SMTP Server zur Exchange Konfiguration hinzufügen

$a = (Get-TransportConfig).InternalSMTPServers ; $a += "192.168.10.5" ; Set-TransportConfig -InternalSMTPServers $a

Windows Services (Dienste) mittels Powershell starten

Habe mir in Windows Powershell einen netten Einzeiler zurechtgelegt, der mir automatisch alle Dienste startet, die eigentlich automatisch starten sollten, aber (aus welchem Grund auch immer) nicht laufen.
Auf einigen meiner Server kommt es immer mal wieder vor, das Services nicht laufen, die eigentlich laufen sollen. Mit diesem Powershell Skript ist das Problem schnell behoben:

Get-WmiObject Win32_Service | where {$_.StartMode -eq "Auto"} | where {$_.State -eq "Stopped"} | Start-Service

Podcatcher mit Powershell v2 & BITS

Vor kurzem habe ich einen Podcatcher mit Powershell und BITS (“Background Intelligent Transfer Service”) geschrieben, für den man aber zusätzlich noch bitsadmin.exe und bget.cmd benötigt.
Da bitsadmin.exe eher mühsam und bget.cmd zwar nett aber etwas buggy ist, bin ich gleich auf die schon damals angeführte Möglichkeit umgestiegen, Powershell v2 (CTP 3) zu verwenden – damit braucht man nämlich keine zusätzlichen Tools mehr.

Das ganze funktioniert bisher recht robust – ich möchte nur noch eine (visuelle) Statusanzeige dazu programmieren.

param ([switch] $schedule)
#Set-PSDebug -Trace 1
Import-Module FileTransfer -Verbose

$today = get-date
$yesterday = $today.AddDays(-1)
$today = Get-Date -date $today -uformat "%Y%m%d"
$yesterday = Get-Date -date $yesterday -uformat "%Y%m%d"
$today = $today.tostring()
$yesterday = $yesterday.tostring()

if ($schedule) {
$taskname = $myinvocation.mycommand.definition -replace '\W','_'
schtasks /create /ru PIVO9\Christian /rl HÖCHSTE /sc MINUTE /MO 5 /tn "$taskname" /tr "%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell -c $($myinvocation.mycommand.definition)"
return;
}

pushd (split-path -parent $myinvocation.mycommand.definition)

$feed=[xml](New-Object System.Net.WebClient).DownloadString("http://***.*****.net/mythfeed/feed.php")
foreach($i in $feed.rss.channel.item) {
    $url = New-Object System.Uri($i.enclosure.url)
    $absURL = $url.AbsoluteUri   
    $filename = "C:\Users\Public\Videos\ElskeTV\" + $url.Segments[-1]
    If ((Test-Path $filename) -eq $FALSE) 
    {
echo ----------------------------------------------------------------------------------------------------
echo $url.Segments[-1]

$joblist = Get-FileTransfer
$jobexist = $false

foreach ($i in $joblist) {

foreach ($j in $i.filelist) {
if ($j.IsTransferComplete) { Complete-FileTransfer $i }
if ($j.RemoteName -eq $absURL) {
echo "Job wurde gefunden..."
if ($j.BytesTotal -gt 0) { "{0:P1}" -f  ($j.BytesTransferred / $j.BytesTotal) }
$i.JobState
$i.CreationTime
$jobexist = $true
if ($j.RemoteName -match $today) {$i | Set-FileTransfer -Priority "FOREGROUND" }
if ($j.RemoteName -match $yesterday) {$i | Set-FileTransfer -Priority "FOREGROUND" }
}
}}

if ($jobexist -eq $false) {
New-FileTransfer -ServerFileName $absURL -ClientFileNamePrefix C:\users\Public\videos\ElskeTV\ -Displayname $url.Segments[-1] -Asynchronous
Echo "Neuer Download-Job wurde hinzugefügt!"
}

    }
}

echo ----------------------------------------------------------------------------------------------------

popd

#Fortschritt in Prozent der einzelnen Downloads
#$joblist = Get-FileTransfer ; foreach ($i in $joblist) { foreach ($j in $i.filelist) { if ($j.BytesTotal -gt 0) { "{0:P1}" -f  ($j.BytesTransferred / $j.BytesTotal) }}}

#Summe aller übertragenen Bytes aller Downloadjobs
#$joblist = Get-FileTransfer ; $total = 0 ; foreach ($i in $joblist) { foreach ($j in $i.filelist) { if ($j.BytesTotal -gt 0) {$total = $total + $j.BytesTransferred}}} ; $total ; get-date

#Downloadjobs auflisten, die in den letzten 10 Minuten erstellt wurden
#get-FileTransfer | Where {$(Get-Date).AddMinutes(-10) -lt $_.CreationTime}

#Dateien auflisten mit einem bestimmten Datum im Dateinamen
#$joblist = Get-FileTransfer ; foreach ($i in $joblist) { foreach ($j in $i.filelist) { if ($j.RemoteName -match "20090418") {$i | fl * } }}

#Priority hochsetzen für Downloads mit einem bestimmten Datum im Dateinamen
#$joblist = Get-FileTransfer ; foreach ($i in $joblist) { foreach ($j in $i.filelist) { if ($j.RemoteName -match "20090418") {$i | Set-FileTransfer -Priority "FOREGROUND" } }}

 

 

Podcatcher mittels Powershell und BITS

Das BITS (“Background Intelligent Transfer Service”) ist ein Windows Dienst der sich um den Download von (größeren) Dateien ressourcen und netzwerkschonend im Hintergrund kümmert. Da er als Service läuft und auch Resumes unterstützt, kann auch ein Reboot einem mit BITS initiierten Download nichts anhaben. Ursprünglich nur für Windows Updates gedacht, kann man BITS mit dem Tool bitsadmin.exe auch für andere/eigene Downloads nutzen.
Bitsadmin.exe bekommt man bei älteren Windows Versionen über die Windows Support Tools, ab Windows Vista ist es bereits enthalten.
Da bitsadmin.exe nicht besonders userfreundlich ist, verwende ich bget.cmd zur Steuerung von BITS download jobs.
Ich habe einige Video Podcasts (mit US Fernsehsendungen), die ich regelmäßig herunterladen möchte, und mit allen verfügbaren Podcatchern für Windows (inkl. iTunes) bin ich mehr als unzufrieden. Daher lag die Idee nahe, einen eigenen Podcatcher mit Powershell zu schreiben.

Nichts leichter als das!

Man nehme:

  • Powershell 1.0
  • bitsadmin.exe
  • bget.cmd (hier)

podcatcher.ps1

$feed=[xml](New-Object System.Net.WebClient).DownloadString("http://podcast.msnbc.com/audio/podcast/MSNBC-NN-NETCAST-M4V.xml")
foreach($i in $feed.rss.channel.item) {
    $url = New-Object System.Uri($i.enclosure.url)
   
$absURL = $url.AbsoluteUri   
    $filename = "D:\Videos\" + $url.Segments[-1]
    If ((Test-Path $filename) -eq $FALSE) 
    {
    bget """$absURL""" """$filename""" –b
    }
}

Zuerst hole ich mir das XML File des RSS Feed herunter. Dann loope ich durch alle items, und lasse mir die enclosure URLs zurückgeben. Als Objekt vom Typ System.Uri kann ich hier unter anderem auf die Parameter AbsoluteUri (ganze URL, bereits urlencoded, falls das im Feed nicht der Fall war) und segments[-1], welcher mir nur den Dateinamen zurückgibt, zugreifen.
Schließlich stelle ich noch sicher, dass das File im Zielpfad nicht existiert, und dann übergebe ich URL, Filename und den Batch Parameter “-b” an bget.
BITS erstellt das File im Zielordner erst, wenn es fertig heruntergeladen ist. Das ist auch praktisch im Vergleich zu anderen Podcatchern, so landen keine unfertigen Videos im Video-Ordner.
BITS und bget kümmern sich auch von selbst darum, dass ein File dass bereits heruntergeladen wird, nicht nochmal heruntergeladen wird (anhand der URL).
So muß ich podcatcher.ps1 nur mehr in der Aufgabenplanung regelmäßig ausführen, und ich habe einen perfekten podcatcher der absolut robust ist und mir nicht mehr ein Verzeichnis mit halbfertig heruntergeladenen Video Files hinterläßt, so wie seine Vorgänger.

Übrigens: Schön, wieder mal sagen zu können “In Windows 7 wird alles besser” – Genauer gesagt in PowerShell 2.0, das in Windows 7 und Windows Server 2008 R2 bereits enthalten sein wird. Da brauchen wir dann nämlich weder bitsadmin.exe noch bget.cmd sondern können BITS komplett mittels Powershell Cmdlets (z.B. 'New-FileTransfer') steuern. Mehr dazu hier -  die Syntax ist aber noch nicht ganz final. Wenn Powershell 2.0 final ist, werde ich dieses Skript umschreiben.

Per Skript die Priorität von Prozessen verändern

Die unglaubliche Macht von WSH (oder Powershell) in Kombination mit WMI ist mir schon länger bekannt. Ich möchte das für mich nutzen, um ein Skript zu schreiben, dass mir auf Klick (oder ereignisgesteuert) alle Prozesse mit einem bestimmten Namen beschleunigt oder abbremst, also die Priorität verändert.

Wie mache ich das? Mit einem Skript namens setprio.vbs, das zwei Parameter entgegennimmt, nämlich ‘Processname’ (in Kleinbuchstaben) und ‘DesiredPriority’
DesiredPriority kann einen dieser Werte haben:
IDLE|BELOW_NORMAL|NORMAL|ABOVE_NORMAL|HIGH_PRIORITY|REALTIME
In meinem Skript führt ein ungültiger Wert automatisch dazu, dass der Prozess auf ‘NORMAL’ zurückgesetzt wird.

Mit diesem Befehl werden also alle Internet Explorer Prozesse abgebremst:
cscript setprio.vbs iexplore.exe BELOW_NORMAL

image

Wofür kann man nun sowas in der Praxis wirklich brauchen?
Also: Man nehme an, man hat eine sehr große Musik- oder Videobibliothek umzuwandeln (wir sprechen von vielen Tagen, wenn nicht Wochen Rechenarbeit!), möchte aber z.B. unter Tags auf dem Rechner normal arbeiten können, dann muss man z.B. in der Früh nur diesen Befehl ausführen:
cscript setprio.vbs convertvideo.exe BELOW_NORMAL
Vor dem Schlafen gehen dann:
cscript setprio.vbs convertvideo.exe ABOVE_NORMAL
Natürlich kann man auch IDLE oder REALTIME nehmen, bzw. das ganze zeitgesteuert machen oder (unter Vista, Windows Server 2008 oder Windows 7) das ganze ereignisgesteuert machen.
Das Skript ist natürlich auch hervorragend etwa für einen (Home-)server oder ein Media Center geeignet, um die schwächeren Stunden oder die Nacht perfekt für Rechenaufgaben zu nützen. Ich werde mir das mittels Ereignissteuerung so konfigurieren, dass bestimmte Prozesse automatisch eine höhere oder sehr hohe Priority bekommen, wenn niemand vor dem Computer sitzt (=Bildschirm schwarz), und die Prozesse sofort in den Hintergrund fliegen, sobald der PC wieder benutzt wird.

Normalerweise schreibe ich gerne kurze, lesbare Skripts, ich habe hier bewußt etwas ausgefeiltere Rückmeldungen und Fehlerbehandlungen eingebaut. Mit Powershell wäre das natürlich sogar als Einzeiler realisierbar gewesen. Aber Powershell ist halt noch nicht auf jedem Windows PC standardmäßig installiert, daher bevorzuge ich zur Zeit (von Exchange 2007 Servern abgesehen) noch WSH/VBScript:

set args = WScript.Arguments
num = args.Count

'Error handling if no command line parameters given
if num < 2 then
   WScript.Echo "No command line parameters!"
   WScript.Echo "Syntax: cscript setprio.vbs ProcessName DesiredPriority"
   WScript.Echo "DesiredPriority can be: "
   WScript.Echo "IDLE|BELOW_NORMAL|NORMAL|ABOVE_NORMAL|HIGH_PRIORITY|REALTIME"
   WScript.Quit 1
end if

ProcessName   =     args.Item(0)
DesiredPriority =    args.Item(1)

strComputer = "."

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

Set colItems = objWMIService.ExecQuery("Select * From Win32_Process")

'Here all Processes will be found,
'
that contain the ProcessName and the Sub SetPID will be called
For Each objItem in colItems
    If InStr(lcase(objItem.Name), ProcessName) Then
        '    Use objItem.CommandLine instead of objItem.Name
        '    if you want to match a string as part of the
        '    full commandline for the process!
    Call SetPID (objItem.ProcessID, GetPriorityID (DesiredPriority))
    End If
Next

'Here the Processes will be set to the desired priority
Sub SetPID (intPID, intPriority)

    set objWMIProcess = GetObject("winmgmts:\\" & strComputer & "\root\cimv2:Win32_Process.Handle='" & intPID & "'")
    intErrorCode = objWMIProcess.SetPriority(intPriority)
    if intRC = 0 Then
       Wscript.Echo "Successfully set priority for process " & objWMIProcess.Name & " (ID: " & intPID & ") to " & GetPriorityName(intPriority)
    else
       Wscript.Echo "Error: '" & intErrorCode & "' setting priority for process " & objWMIProcess.Name & "(ID: " & intPID & ") to " & GetPriorityName(intPriority)
    end if
       Wscript.Echo "(Command: '" & objItem.CommandLine & "')"
       Wscript.Echo vbcrLF
End Sub

'These two functions aren't really necessary, they just translate
'
the more readable priority names into the numbers
'required by objWMIProcess.SetPriority

Function GetPriorityName (intPriority)
    Select Case intPriority
        Case 32:     GetPriorityName = "NORMAL"
        Case 64:     GetPriorityName = "IDLE"
        Case 128:     GetPriorityName = "HIGH_PRIORITY"
        Case 256:     GetPriorityName = "REALTIME"
        Case 16384:     GetPriorityName = "BELOW_NORMAL"
        Case 32768:     GetPriorityName = "ABOVE_NORMAL"
    End Select
End Function

Function GetPriorityID (strPriorityName)
    Select Case strPriorityName
        Case "NORMAL":        GetPriorityID = 32
        Case "IDLE":        GetPriorityID = 64
        Case "HIGH_PRIORITY":    GetPriorityID = 128
        Case "REALTIME":    GetPriorityID = 256
        Case "BELOW_NORMAL":    GetPriorityID = 16384
        Case "ABOVE_NORMAL":    GetPriorityID = 32768
        'Invalid Priorityname resets Priority to 'NORMAL'
        Case ELSE:        GetPriorityID = 32
    End Select
End Function

Hier noch eine verkürzte Version davon, nur um zu zeigen, dass es natürlich auch kürzer geht, wenn man etwa die Parameter direkt in’s Skript gibt, und nicht ganz so viele Ausgaben macht:

strComputer = "."

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

Set colItems = objWMIService.ExecQuery("Select * From Win32_Process")

For Each objItem in colItems
    If InStr(lcase(objItem.Name), "notepad.exe") Then
    Call SetPID (objItem.ProcessID, 16384)
    End If
Next

Sub SetPID (intPID, intPriority)

    set objWMIProcess = GetObject("winmgmts:\\" & strComputer & "\root\cimv2:Win32_Process.Handle='" & intPID & "'")
    intErrorCode = objWMIProcess.SetPriority(intPriority)
    if intRC = 0 Then
       Wscript.Echo "Successfully set priority for process " & objWMIProcess.Name & " (ID: " & intPID & ")"
    else
       Wscript.Echo "Error: '" & intErrorCode & "' setting priority for process " & objWMIProcess.Name & "(ID: " & intPID & ")"
    end if
End Sub

Weitere Informationen: Das Einrichten von ereignisgesteuerten Aufgaben erkläre ich in einem anderen Zusammenhang in diesem Beitrag.

Dell Seriennummer auslesen

Dieses nette kleine Skript liest die Seriennummer von Dell Servern (aber auch PCs und Laptops) aus:

serial.vbs

Set wmiobj = GetObject("winmgmts://localhost/root/cimv2:Win32_BIOS")
For each ver in wmiobj.Instances_
MsgBox ver.SerialNumber
Next

Auf einem Dell Server und auf einem Dell Laptop getestet, sollte aber auch bei anderen Marken funktionieren, die Ihre Seriennummer im Bios hinterlegen.

Facebook

Letzte Tweets

Twitter Mai 26, 23:39
Gelbe Engel! Danke!

Twitter Mai 18, 21:34
Finland was terrible. #Eurovision

Twitter Mai 17, 12:49
just blogged Ist das Surface Pro teuer? – Ein Fact-Check: Gestern wurde angekündigt, dass das Surface Pro in D... http://t.co/PhW7qzhkUq

Folge mir auf Twitter!

Über den Autor

MCTS

Christian Haberl Christian Haberl ist seit mehr als 10 Jahren als EDV Berater, Vortragender und Trainer tätig. Er kann sich nicht für ein Spezialgebiet entscheiden, drum heißt dieser Blog auch "Kraut & Rüben Blog" - Unter seine Interessen fallen Web-Entwicklung auf ASP.NET Basis, Information Worker & Productivity Technologien (Windows, Office), Server (Windows Server, Small Business, Virtualisierung, Exchange), Scripting, Spam Filtering/Security und Digital Home. Christian Haberl ist auch einer der führenden Produktspezialisten für Windows Media Center und Windows Home Server und ist Direktor des ClubDigitalHome.
Im Jahr 2008 hat Christian Haberl über 200 Vorträge und Schulungen durchgeführt.
Im Frühjahr 2009 wurde Christian Haberl von Microsoft Österreich zum "Influencer" ernannt, weiters wurde er Microsoft Certified Technology Specialist / Microsoft Certified Connected Home Integrator sowie Microsoft Certified Consumer Sales Specialist.

Month List

Netzwerk Management

Bandwidth

RecentComments

Comment RSS