Search PowerShellers and other PowerShell-related sites

Monday, November 10, 2008

-include and -exclude go together

While reading James Brundage's blog post Microcode: Exploring More of .NET with Get-Assembly, I have spotted a rather unnecessary complicated part of a code:

Get-ChildItem (Join-Path $env:Windir "Assembly") -recurse -filter "*.dll" |
Where-Object {
! $_.Name.Substring(0,$_.Name.IndexOf($_.Extension)).EndsWith(".ni")
}


The goal was to remove from the list of the DLLs those files named something like AssemblyName.Ni.Dll, because they cannot be loaded. At first I thought this is the right job for a -notlike operator:

Get-ChildItem (Join-Path $env:Windir "Assembly") -recurse -filter "*.dll" |
Where-Object {$_.name -notlike "*.ni.*"}


It'll do the job and it's much cleaner (and simpler).

On the other hand, Get-ChildItem has an -exclude parameter. It must be faster than piping to Where-Object. Why not use that instead? To my surprise the combination of -filter and -exclude parameters produced totally wrong result.

Fortunately, Get-ChildItem has an -include parameter too, which can be used instead of a -filter in this case (hat tip to Joel 'Jaykul' Bennett). So, the final command is:

Get-ChildItem (Join-Path $env:Windir "Assembly") -recurse -include "*.dll" -exclude "*.ni.*"


Isn't that easier to write (and probably faster to execute)?

Monday, October 6, 2008

An interview with Tobias Weltner

For those of you who have missed it when it was broadcasted live, new episode of famous PowerScripting Podcast is online and ready for listening. In this episode Tobias Weltner gives an inside look at PowerShellPlus Professional Edition. Hal Rottenberg and Jonathan Walz had a bag full of great questions (with a nice contribution from the guys in the ustream.tv chat room) and it seems that Tobias was more than willing to give them in-depth coverage of the PowerShellPlus history and new features in version 2.0.

Tuesday, August 12, 2008

"LDAP query" versus "WHERE"

Here is the good example for Jeffrey Snover's post "When NOT To Use "WHERE"". This is original Andrey Moiseev's one-liner to get a list of all computed attributes in AD, mentioned in Dmitry Sotnikov's post "List all Constructed Attributes"

Get-QADObject -SearchRoot "CN=Schema,CN=Configuration,dc=MyDomain,dc=COM" -Type attributeSchema -IncludedProperties systemFlags -SizeLimit 0 | where {$_.SystemFlags -band 4}


This one-liner needs 120 seconds to complete on my system.

Let's try the same thing, but this time with LDAP query:

Get-QADObject -SearchRoot "CN=Schema,CN=Configuration,dc=MyDomain,dc=COM" -ldapfilter '(systemFlags:1.2.840.113556.1.4.803:=4)' -Type attributeSchema -IncludedProperties systemFlags -SizeLimit 0


I can see a list of all computed attributes in AD in just 3 seconds.

Tuesday, June 10, 2008

The "#requires" statement

Most of us are familiar with #requires -version 2. Jeffrey Snover had written about versioning just before the release of a Community Technology Preview (CTP) of Windows PowerShell v2.0. You start your script with
#requires -version 2
and PowerShell will check version #'s and produce a precise error message.

The "#requires" statement is not a new feature of PowerShell v2. It's with us from the PowerShell v1, but no one cared outside the PowerShell team. ;-)

Do you know that you can check for the presence of the other things too?

The "#requires" statement must be in one of the following formats:
"#requires -shellid <shellid>"
"#requires -version <major.minor>"
"#requires -pssnapin <pssnapinname>[-version <major.minor>]"


For example, you can check if quest.activeroles.admanagement snap-in is added to the current console. Put #requires -pssnapin quest.activeroles.admanagement in your script, and if the snap-in isn't added, you will get nice error message.

The script 'test.ps1' cannot be run because the following Windows PowerShell snap-ins that are specified
by its "#requires" statements are missing: quest.activeroles.admanagement.


By the way, is there any other reserved "comment" statement?

Thursday, May 29, 2008

Search PowerShellCentral Script Repository

This is simple function that will help you search PowerShellCentral Script Repository right from the command line.

function Search-PSCentral {
param([string]$keyword)
(New-Object –com Shell.Application).Open("http://powershellcentral.com/scripts/?lang=&q=*$keyword*")
}


Usage: Search-PSCentral ini

If you leave out a keyword or there are no results, the page will open ready for you to paste in some code and fill the gap. :-)

Friday, November 9, 2007

SDM GPMC PowerShell Cmdlets 1.0

From now on SDM Software is offering SDM GPMC PowerShell Cmdlets 1.0 for free. This version comes with 9 cmdlets for performing GPO management tasks from creating and deleting GPOs, to linking and unlinking them, to modifying GPO security, to backing up and restoring GPOs. After installation you can run them from Start menu or you can add snap-in to your profile file.

Add-PSSnapin SDMGPOSnapIn

After the snap-in is added, you can use 9 new cmdlets.

PS>get-command *sdm* -commandtype cmdlet
Name
----
Add-SDMgplink
Add-SDMgpoSecurity
Export-SDMgpo
Get-SDMgpo
Get-SDMgpoSecurity
Import-SDMgpo
New-SDMgpo
Remove-SDMgpo
Remove-SDMgpoSecurity

Monday, July 2, 2007

Translate with Google Dictionary Translation and PowerShell

Google Translate has added a nifty new feature: dictionary translation. Dictionary translation is currently available between English and French, Italian, German, Spanish, and Korean. You can get it right from the command line with a little help from PowerShell.



# Usage:
# Get-Translation -word power -dictionary ef
# Get-Translation shell ei
# gt "ab und zu" de

Function Get-Translation {
param([string]$word="",[string]$dictionary="")

switch($dictionary) {
ef {$langpair = "en%7Cfr"} # English-French
fe {$langpair = "fr%7Cen"} # French-English
ed {$langpair = "en%7Cde"} # English-German BETA
de {$langpair = "de%7Cen"} # German-English BETA
ei {$langpair = "en%7Cit"} # English-Italian
ie {$langpair = "it%7Cen"} # Italian-English
ek {$langpair = "en%7Cko"} # English-Korean
ke {$langpair = "ko%7Cen"} # Korean-English
es {$langpair = "en%7Ces"} # English-Spanish
se {$langpair = "es%7Cen"} # Spanish-English
}

$objIE = New-Object -Com Internetexplorer.Application
$url = "http://translate.google.com/translate_dict?q=" + $word + "&sa=N&hl=en&langpair=" + $langpair
$objIE.Navigate($url)
$objIE.Visible=$true
}

Set-Alias gt Get-Translation




A dictionary translation of your word or short phrase will be displayed in Internet Explorer.

Monday, May 21, 2007

How to easy format date/time

One of the easiest ways to format date and time is the command

get-date -format <string>


<string> represents the format specifier. For a list of available format specifiers, see the System.Globalization.DateTimeFormatInfo Class topic in MSDN or look at these examples:


PS> get-date -format d
5/21/2007
PS> get-date -format D
Monday, May 21, 2007
PS> get-date -format f
Monday, May 21, 2007 9:24 PM
PS> get-date -format F
Monday, May 21, 2007 9:24:41 PM
PS> get-date -format g
5/21/2007 9:24 PM
PS> get-date -format G
5/21/2007 9:24:50 PM
PS> get-date -format m
May 21
PS> get-date -format M
May 21
PS> get-date -format o
2007-05-21T21:25:03.4218750+02:00
PS> get-date -format r
Mon, 21 May 2007 21:25:09 GMT
PS> get-date -format R
Mon, 21 May 2007 21:25:12 GMT
PS> get-date -format s
2007-05-21T21:25:17
PS> get-date -format t
9:25 PM
PS> get-date -format T
9:25:23 PM
PS> get-date -format u
2007-05-21 21:25:28Z
PS> get-date -format U
Monday, May 21, 2007 7:25:34 PM
PS> get-date -format y
May, 2007
PS> get-date -format Y
May, 2007



This blog entry has been inspired by Per Ostergaard and Jeffrey Snover.

Monday, March 26, 2007

Spring-cleaning of a PowerShell profile

After I read James Manning's post why share-able functions shouldn't be in your PowerShell profile, I have looked in my $profile. It was far from small file focused on prompt function, transcript function, one-liners and aliases. So, I created a few subfolders (AD, ISA, Exchange, Misc, Test...) for my scripts in WindowsPowerShell folder. Also, the functions found their place in dedicated folder Functions. The only thing that left is to put all folders with scripts in my path and to dot-source functions from Functions folder.


$profilehome = ([System.IO.FileInfo]$PROFILE).DirectoryName

dir $profilehome | where {$_.PsIsContainer -and ($_.name -ne "functions")} | %{$env:path += ";" + $profilehome + "\" + $_.name}

dir ($profilehome + "\functions") | where {!$_.PsIsContainer} |
%{. ($profilehome + "\functions\" + $_.name)}



$profile is now clean and tidy, and in James Manning's words - it's a far more robust, maintainable, shareable, and supportable situation than before.

Wednesday, March 14, 2007

Daily notes with PowerShell

The post at Holistic Detection blog gave me an idea how to keep my daily notes organized and just a few keystrokes away.


function New-DailyNotes {

# store files in subfolder notes in WindowsPowerShell folder
$path = (join-path ([System.IO.FileInfo]$profile).DirectoryName \notes\)
# files will be named like 2007-03-14_notes.txt
$notesfile = (get-date).ToString("yyyy-MM-dd") + "_notes.txt"

if( !(test-path $path ) )
{
# create the notes directory if it doesn't exist
new-item -path $path -type directory
}

$notespath = (join-path $path $notesfile)
if( !(test-path $notespath ) )
{
# create the notes file if it doesn't exist
new-item -path $path -name $notesfile -type "file"
notepad $notespath
}
else
{
notepad $notespath
}

}

set-alias dn New-DailyNotes



I've added this function to the profile file and I only have to type dn to get access to my daily notes file.

Sunday, November 12, 2006

Osnove - Uvod u objektni model

Ključna stvar u čemu se Windows PowerShell razlikuje od sličnih shell okruženja jeste osobina da radi isključivo sa objektima. Rezultat komande koju kucate u shell-u na Linux-u je tekst. Na primer

#ps -e
PID TTY TIME CMD
1 ? 00:08:00 init
12021 ? 00:00:00 kdm



Ukoliko sada želimo da prekinemo proces kdm moramo da izdvojimo deo teksta koji se odnosi na broj procesa (PID kolona) i da ga prosledimo kao parametar komandi za prekid procesa (kill).

# ps -e | grep " kdm" | awk '{ print $1 }' | xargs kill



Problem ovog pristupa je da veci deo vremena provodimo formatirajući tekst, što može da bude složeno i zamorno, ali se zato sve komanda se izvršavaju gotovo trenutno.

Windows PowerShall sa druge strane radi sa objektima. Pogledajmo šta se dešava ako otkucamo komandu dir

PS> dir

Directory: Microsoft.PowerShell.Core\FileSystem::C:\

Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 9/23/2006 2:23 PM ATI
d---- 9/21/2006 10:41 PM Documents and Settings
...



Iako reuzultat izgleda kao par redova teksta, u stari u pitanju je niz objekata koji su tipa System.IO.FileInfo. Ukoliko vas ovo podseća na .NET, u pravu ste, osnova Windows PowerShell-a jeste .NET.

Komande su u stvari funkcije čiji su ulazi i izlazi objekti. Ako se vratimo našem primeru koji prekida proces kdm, ekvivalentan primer bi u PS bi bio:

PS> get-process kdm | stop-process



Vidi se da je zapis mnogo čitljiviji, jedina mana je što se malo gubino na brzini. Meni se iskreno ovo mnogo više sviđa, jer se kod lakše i brže piše.

Ovo se može mnogo bolje videti na malo složenijem primeru, sledeće komande prekidaju sve procese koji troše više od 10MB memorije.

bash

# ps -el | awk '{ if ( $6 > (1024*10)) { print $3 } }' | grep -v PID | xargs kill



Windows PowerShell

PS> get-process | where { $_.VS -gt 10M } | stop-process



Čak i ako nikada niste videli PowerShell, velika je verovatnoća da će te samo na osnovu koda razumeti o čemu se radi. Što se bash-a tiče tu ne bih bio tako siguran.

Ovo je tek početak, u sledećem tekstu videćemo da su i promenljive objekti. Takođe videćemo kako lako možemo da saznamo koji svi properties i methods postoje za neki objekat.

Friday, October 20, 2006

Code Test 2

1: $a = ipconfig /all | findstr "172.16.1." | %{$_.remove(0,44)}
2: route add 192.168.0.0 mask 255.255.0.0 $a

Thursday, October 19, 2006

Da li ste već čuli za Windows PowerShell?

Windows PowerShell. Najvrelija stvar koja ovih dana stiže iz Redmonda. Šta je Windows PowerShell? Da se ne bih pravio pametniji od samih tvoraca, pravo je vreme da ubacim mali citat, direktno sa MS sajta - "Microsoft Windows PowerShell command line shell and scripting language helps IT Professionals achieve greater productivity. Using a new admin-focused scripting language, more than 130 standard command line tools, and consistent syntax and utilities, Windows PowerShell allows IT Professionals to more easily control system administration and accelerate automation." Ključne reči su: command line shell, scripting language i admin-focused.

Kao da se svakog dana pojavljuju novi blogovi koji se njime bave (a još se nije ni pojavila finalna verzija). Jedna od udarnih tema na Tech·Ed 2007 u Barseloni biće upravo PowerShell. Informacija ima toliko da čovek ne zna šta pre da pročita, koji skript pre da proba. Odabrane izvore informacija naći ćete u okviru sidebar-a. U vrlo skoroj budućnosti nećete moći administirati Windows sisteme bez znanja PowerShell-a. Ne čekajte finalnu verziju. Preuzmite trenutno aktuelan Windows Powershell 1.0 RC2 (potreban vam je i .NET Framework 2.0, ako ga već nemate instaliran) i zaronite u najbolji shell na svetu. The shell must flow.