Tuesday, July 22, 2008

Blog Relocation - Reminder


This blog has moved, please update your links:

RSS Feed: http://feeds.feedburner.com/ShayLevy
New Blog URL: http://PowerShay.com

-Shay

Monday, July 7, 2008

Blog relocation

 

My blog is moving to Microsoft's Israel blogs community. The new RSS feed is:

http://feeds.feedburner.com/ShayLevy

New posts will be published here: http://blogs.microsoft.co.il/blogs/ScriptFanatic/


Please update your feed reader.

 

-Shay

Sunday, July 6, 2008

Free eBook - Introducing SQL Server 2008

 

Microsoft is offering Introducing SQL Server 2008 by Peter DeBetta for free. Learn about major new features in SQL Server 2008 including security, administration, and performance.

Friday, July 4, 2008

IIS7 PowerShell Provider Tech Preview 2

 

The second CTP of the IIS7 Powershell provider has released bumping up the total number of cmdlets to 55!

After you download and install the provider you can start exploring it with the pre-built PowerShell console file:

Click on the Start Menu -> "All Programs" -> "IIS 7.0 Extensions" -> "IIS PowerShell Management Console".

The prompt of the new PowerShell command window is set to "IIS:\" - the root of the IIS Provider namespace.

image

 

In the example below I'm loading the provider snap-in (manually) into my current PowerShell session.

# find the IIS snap-in name
PS > Get-PSSnapin -Registered

Name        : IIsProviderSnapIn
PSVersion   : 1.0
Description : IIS Administration Provider

 

# load the snap-in


PS > Add-PSSnapin IIsProviderSnapIn

 

# get a list off all cmdlets name in the provider
PS > Get-Command -PSSnapin IIsProviderSnapIn | select name

Name
----
Add-WebConfiguration
Add-WebConfigurationProperty
Backup-WebConfiguration
Begin-CommitDelay
Clear-FrebData
Clear-WebConfiguration
ConvertTo-WebApplication
Disable-Freb
Disable-WebModule
Enable-Freb
Enable-WebModule
End-CommitDelay
Get-AppDomain
Get-AppPoolState
Get-ConfigurationBackup
Get-URL
Get-WebConfiguration
Get-WebConfigurationProperty
Get-WebHandler
Get-WebItemState
Get-WebModule
Get-WebRequest
Get-WebSiteState
New-AppPool
New-FtpSite
New-ManagedWebModule
New-VirtualDirectory
New-WebApplication
New-WebBinding
New-WebHandler
New-WebModule
New-WebSite
Remove-AppPool
Remove-ConfigurationBackup
Remove-VirtualDirectory
Remove-WebApplication
Remove-WebBinding
Remove-WebConfigurationProperty
Remove-WebHandler
Remove-WebModule
Remove-WebSite
Restart-AppPool
Restart-WebItem
Restore-WebConfiguration
Set-WebBinding
Set-WebConfiguration
Set-WebConfigurationProperty
Set-WebHandler
Set-WebModule
Start-AppPool
Start-WebItem
Start-WebSite
Stop-AppPool
Stop-WebItem
Stop-WebSite

 

To navigate the namespace simply set your location to the root of the IIS Provider namespace, now you can navigate using the get-childitem (dir for short):  

PS > cd iis: 
PS > dir 

Name
----
Sites
AppPools
SslBindings 

 

One thing I've noticed is the lack of command completion when navigating the provider hierarchy. For example, cd si<tab> or dir iis:\si<tab> doesn't resolve to the sites container. Only after manually executing 'dir iis:\sites' the list of sites became available for upcoming dir requests.

To get a list of web sites we list the sites container which returns a site collection:

PS > dir iis:\sites
Name ID State Physical Path Bindings ---- -- ----- ------------- -------- Default Web Site 1 Started %SystemDrive%\inetpub\wwwroot http *:80: test1 2 Started http *:80:test1 test2 3 Started http *:80:test2




 

The same applies for the AppPool container. It can be quiet long to type this each time you want to get all (or even one) web sites or app pools. I excepted to find corresponding cmdlets such as Get-WebSite or Get-AppPool but there are no.

PS > get-command -noun appp* -pss iis* | select name

CommandType     Name
-----------     ----
Cmdlet          Get-AppPoolState
Cmdlet          New-AppPool
Cmdlet          Remove-AppPool
Cmdlet          Restart-AppPool
Cmdlet          Start-AppPool
Cmdlet          Stop-AppPool


PS > get-command -noun webs* -pss iis* | select name

CommandType     Name
-----------     ----
Cmdlet          Get-WebSiteState
Cmdlet          New-WebSite
Cmdlet          Remove-WebSite
Cmdlet          Start-WebSite
Cmdlet          Stop-WebSite

 

You can overcome the absence of this cmdlets by defining your own functions to get this objects:

PS > function Get-WebSite($name='*') {Get-Item IIS:\Sites\$name}
PS > function Get-AppPool($name='*') {Get-Item IIS:\AppPools\$name} # get all websites PS 153> Get-WebSite Name ID State Physical Path Bindings ---- -- ----- ------------- -------- Default Web Site 1 Started %SystemDrive%\inetpub\wwwroot http *:80: test1 2 Started http *:80:test1 test2 3 Started http *:80:test2


# get a website name using wildcards
PS > Get-WebSite def* Name ID State Physical Path Bindings ---- -- ----- ------------- -------- Default Web Site 1 Started %SystemDrive%\inetpub\wwwroot http *:80:

 

OK, time to build a new site. There is a new cmdlet just for that:

PS > New-Website -name NewWebsite Name ID State Physical Path Bindings ---- -- ----- ------------- -------- NewWebsite 4 http *:80:NewWebsite New-WebSite : The object identifier does not represent a valid object.
Exception from HRESULT: 0x800710D8) At line:1 char:12 + New-Website <<<< -name NewWebsite


  

# the site was created but with an error. I'm not sure what is the
# cause so I logged a comment on that IIS.net forums # I found that if you assign the command to a # variable then the error is gone # e.g. $newSite = New-WebSite -name NewWebSite # despite the error the new site is up and running

PS > Get-WebSite new* Name ID State Physical Path Bindings ---- -- ----- ------------- -------- NewWebsite 4 Started http *:80:NewWebsite

 

Now lets try to remove it: 

PS > Get-WebSite NewWebsite | Remove-WebSite
PS > Get-WebSite

Name             ID State   Physical Path                 Bindings
----             -- -----   -------------                 --------
Default Web Site 1  Started %SystemDrive%\inetpub\wwwroot http *:80:
test1            2  Started                               http *:80:test1
test2            3  Started                               http *:80:test2

 
The site was removed successfully but WITHOUT any warning or confirmation. This is were another PowerShell built-in feature comes to rescue, the -confirm parameter.
When a cmdlet action significantly affects the system, such as by deleting data or by using a significant amount of system resources, Windows PowerShell can automatically prompt you for confirmation before performing the action:
 
PS 197> Get-WebSite new* | Remove-WebSite -Confirm

Confirm
Are you sure you want to perform this action?
Performing operation "Remove-WebSite" on Target "NewWebsite".
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  
[?] Help (default is "Y"):

 

You can get more information on PowerShell's common parameters by typing:

PS > help about_CommonParameters

 

That's it for now :)

Tuesday, July 1, 2008

2008 Microsoft MVP Award

 mvp
I got an email from Microsoft regarding the 2008 Microsoft MVP Award. I was chosen for the award in the Admin Frameworks category (Windows PowerShell).

What a day! What can I say. It feels like walking on the moon. It is an honor to be among the great guys. I would like to thank the people who supported me along the way and to Microsoft for the award.

PowerShell ROCKS!

Monday, June 30, 2008

Do you know your aliases?

 

This little PowerShell script you can check how familiar you are with all the built-in aliases in PowerShell V2 CTP2.
For each alias there are 7 cmdlet names to choose from. There are 10 questions, and at the end of the quiz you can review your results and optionally run the quiz again.

You need to have PowerShell V2 CTP2 installed for the script to run.


Good luck :)

 

 

Thursday, June 26, 2008

ActiveXPoSH - PowerShell for VBScript/JScript

 

SAPIEN Technologies has released a new COM component named ActiveXPoSH (included in PrimalScript 2007 script editor). It is a special PowerShell host that allow developers/scripters to run single cmdlets or entire scripts from VBScript/JScript code. The component is free for personal and commercial use.

You can find more details in this document and download it from here.

Saturday, June 21, 2008

Generating TinyURLs from PowerShell

 

TinyURL is a web service that provides short aliases for long URLs. Here's a function to generate URL aliases using TinyURL's API. The returned URL is short and never expires.

 
function New-TinyUrl($url){
    (new-object net.webclient).downloadString("http://tinyurl.com/api-create.php?url=$url") 
}
 
PS > $vug = New-TinyUrl -url http://marcoshaw.blogspot.com/2008/06/windows-powershell-virtual-user-group.html
PS > $vug
PS > http://tinyurl.com/4k9ons

 

Test it in your default browser:

PS > (new-object -com shell.application).open($vug) 

 

-Shay

Friday, June 20, 2008

Windows PowerShell Virtual User Group #6

 

Marco's Windows PowerShell Virtual User Group #6 is going to take place next week:
Tuesday, Jun 24 7:30pm – 10:30pm (Timezone: Eastern Time)

 

Agenda

8:00PM-8:10PM: Introduction
8:10PM-8:40PM: Bruce Payette (Microsoft)
8:40PM-9:10PM: Wassim Fayed (Microsoft)
9:10PM-9:40PM: Hal Rottenberg
9.40PM-9:50PM: Closing

 

Speaker topics

Bruce Payette : PowerShell v2 modules.
Wassim Fayed : PowerShell v2 remoting.
Hal Rottenberg: Managing VMware Infrastructure using PowerShell.

 

To join for video:
https://www.livemeeting.com/cc/winserver_usergroup/join?id=5H2F88&role=attend&pw=8%5E-%5CzqX

To join for audio:
Toll free: +1 (866) 553-8146
Participant code: 5592528585

 

Required login information (via LiveMeeting)

Meeting ID: 5H2F88
Entry Code: 8^-\zqX

 

Mark your calendar :)

Wednesday, June 18, 2008

Portable PowerShell

 

Hallelujah! Get all the details on Karl Prosser [MVP] blog.

Tuesday, June 17, 2008

Webcast: Managing Hyper-V Virtual Machines with WMI and Windows PowerShell

 

Start Date: Wednesday, July 02, 2008 8:00 AM Pacific Time (US & Canada)

 

Event Overview

Before the beta release of Microsoft System Center Virtual Machine Manager 2008, there was only one option for automating management of Hyper-V virtual machines—Windows Management Instrumentation (WMI). In this webcast, you learn how to automate the most common management tasks, how to create a delegation model using Windows Authorization Manager, and where the power of WMI can pick up where Virtual Machine Manager leaves off. In addition, the Hewlett-Packard Windows Server 2008 Academy team shares their experience automating the deployment of 600 virtual machines in less than three hours using WMI and Windows PowerShell.

 
Presenters: Dung Hoang Khac, Principal Consultant, HP, and Aric Bernard, Senior Technology Consultant, HP

 

Register for the event.

Listing enumeration type values (updated)

 

The old function return duplicate names when the enumeration has two names with the same value, for example: 

 

PS >  Get-EnumValues Microsoft.PowerShell.ExecutionPolicy

        Name Value
        ---- -----
Unrestricted     0
RemoteSigned     1
   AllSigned     2
  Restricted     3
  Restricted     3

 

Here is the modified version of the function:

function Get-EnumValues([type]$type){ 
   [enum]::getNames($type) | select @{n="Name";e={$_}},@{n="Value";e={$type::$_.value__}} | ft -auto
}

 

And the results:

PS >  Get-EnumValues Microsoft.PowerShell.ExecutionPolicy

Name         Value
----         -----
Unrestricted     0
RemoteSigned     1
AllSigned        2
Restricted       3
Default          3
 
-Shay

Monday, June 16, 2008

Scripting Sysadmin meme

 

In response to Steve's Scripting/Sysadmin Meme

 

How old were you when you started programming?

I was 27 when I started to write HTML/ASP pages.

 

What was your first machine?

My first real computer was Windows 95 PC. When I was 12 (I think), my uncle gave me a Texas Instruments (I can't remember the model name) but at that time I wasn't a computer geek.

 

What was the first real script you wrote?

Looping through ADO recordset and populating Active Server Pages (ASP).

 

What scripting languages have you used?

JavaScript/DHTML, VBScript/JScript.
Now that PowerShell is out all other scripting languages are set aside.

 

What was your first professional sysadmin gig?

I started as a sysadmin in a government institution back in 1998 and I'm still holding that position (aside from one year in which I left and returned).

 

If you knew then what you know now, would have started in IT?

Yes. Ever since I have been in the field I have found that being in IT brings out the best in  me.

 

If there is one thing you learned along the way that you would tell new sysadmins, what would it be?

Learn to script! Knowing to script is your sysadmin added value, sorts of a 'super sysadmin' if you will. You'll be able to do magic when your boss wants something that the GUI can't provide.

 

What’s the most fun you’ve ever had scripting?

Every day that passes with Windows PowerShell scripting is a great deal of fun. I learn something new every day.

 

Who am I calling out?

Alexandair Nicolic, Rolf Masuch and Andy Schneider

Sunday, June 15, 2008

PowerShell Popcorn

 

My son heard all the alien beeps and asked me for this one, the Popcorn tune. I couldn't say no :)

 

1..2  | % {
    
    1..2 | % {900,800,900,700,550,700,450 | % { [console]::beep($_,50); sleep -m 150}; sleep -m 250}
    
    900,1000,1050,1000,1050,1000,1050,900,1000,900,1000,800,900,800,900 | % { [console]::beep($_,50); sleep -m 150}
    sleep -m 250
    
    1..2 | % {900,800,900,700,550,700,450 | % { [console]::beep($_,50); sleep -m 150}; sleep -m 250}
    
    900,1000,1050,1000,1050,1000,1050,900,1000,900,1000,800,900,1000,1050 | % { [console]::beep($_,50); sleep -m 150}
    sleep -m 250    

    1..2 | % {
        1..2 | % {1350,1250,1350,1050,800,1050,680 | % { [console]::beep($_,50); sleep -m 150}; sleep -m 250}
        1350,1500,1600,1500,1600,1500,1600,1350,1500,1350,1500,1200,1350,1200,1350 | % { [console]::beep($_,50); sleep -m 150}
        sleep -m 250
    }
}

Saturday, June 14, 2008

Webcast - Using Windows PowerShell with Visual Studio 2008

 

Event Overview

Windows PowerShell is arguably one of the coolest things to happen to developers and administrators alike. Harness the power of the Microsoft .NET Framework from the command line and learn how to write scripts in no time at all. With Windows PowerShell, we leverage your current .NET Framework experience to turn you into one heck of a good scripter.

Presenter: Zain Naboulsi, Developer Evangelist, Microsoft Corporation

The webcast is available for offline viewing.

Friday, June 13, 2008

Enhanced CSV file handling in CTP2

 

In PowerShell v1 you could import comma separated CSV files only. That's not a problem anymore in CTP2. The Import/Export CSV cmdlets got enhanced and now they support a new -delimiter parameter:

 

PS > get-help import-csv -Parameter delimiter

-Delimiter [<char>]
    Specifies the delimiter that separates the property values in the file that is being imported. The default is a com
    ma (,). Enter a character, such as a semicolon (;).

    Required?                    false
    Position?                    2
    Default value                ,
    Accept pipeline input?       false
    Accept wildcard characters?  false

 

Note that the delimiter is limited to a single character.

# Export processes to a space separated csv file
PS > get-process | export-csv -delimiter " " -path processes.csv
# Convert csv files: comma separated to tab separated

PS > import-csv test.csv | export-csv -del "`t" -p test1.csv

Wednesday, June 11, 2008

Close Encounters of the PowerShell Kind

 


Five tones:

$notes = 900,1000,800,400,600
$duration = 400,400,400,400,1600
0..($notes.length-1) | % {[console]::beep($notes[$_],$duration[$_]) }

 

Spaceship Siren:

1..10 | % { 370..470 | % { [console]::beep($_,5) }}

 

Talking alien :)

900,500,1000,800,400,600,1200,300,200,500,1100,300 | %{[console]::beep($_,100)}

 

CTP2 Alien:

1..20 | foreach { 
    
    $rnd = (Get-Random -min 0 -max 20)*100
    
    if($rnd -eq 0) {
        sleep -m 10
    } else {
        [console]::beep($rnd,100)
    }
}

CTP2 - Get Process/Service from remote computers

 

One major change to the Get-Process/Get-Service cmdlets in CTP2 is the ability to get objects from remote computers via a new parameter, computerName (or -c for short). You can map process/service objects to their computer by the machineName member.

 

PS > Get-Service s* -c computer1,computer2 | select name,machineName

Name                  MachineName
----                  -----------
sacsvr                computer2
SamSs                 computer1
SCardSvr              computer1
Schedule              computer1
seclogon              computer1
SENS                  computer1
ServeRAIDManagerAgent computer2
(...)

PS > Get-Process s* -c computer1,computer2 | select name,machineName

Name          MachineName
----          -----------
searchindexer computer1
services      computer2
services      computer1
slp_srvreg    computer2
smax4pnp      computer1
smss          computer2
smss          computer1
snmp          computer2
spoolsv       computer2
spoolsv       computer1
(...)

Sunday, June 1, 2008

Free eBook - TCP/IP Fundamentals for Microsoft Windows

 

The eBook (4.7 MB PDF), from Microsoft, describes the fundamentals of TCP/IP in Windows Vista, Windows Server 2008, Windows XP, and Windows Server 2003.

Thursday, May 29, 2008

Select and then Sort

 

When you use both select-object and sort-object in a pipeline, what's the proper order? Let's check how fast they execute.
Each speed test is built from two similar commands with a different sort/select piping order and each test is executed 10 times. The total execution time is measured in Milliseconds.

 

- Updated: 06/11/2008 (see comment below by Lee Holmes) -

 

Test #1

PS > (measure-Command { 1..10 | foreach { gsv | sort name | select name,status }}).TotalMilliseconds

444.5451


PS > (measure-Command { 1..10 | foreach { gsv | select name,status | sort name}}).TotalMilliseconds

384.7565


Result: Second command is 15% faster.

 

Test #2  

# this command is the third example of select-object command from the help files.

PS > (measure-command { 1..10 | foreach { gps | sort ws | select -last 5 }}).TotalMilliseconds

346.0652


PS > (measure-command { 1..10 | foreach { gps | select -last 5 | sort WS }}).TotalMilliseconds

100.4444
    
Result
: Second command is 3.44 times faster.

# this command is the sixth example of sort-object command from the CTP help files. I changed the extension to ps1.

PS > (measure-Command { 1..10 | foreach { dir *.ps1 | sort @{Expression={$_.LastWriteTime-$_.CreationTime}; Ascending=$
false} | select LastWriteTime, CreationTime}}).TotalMilliseconds
640.9769
PS > (measure-Command { 1..10 | foreach { dir *.ps1 | select LastWriteTime, CreationTime | sort @{Expression={$_.LastWr
iteTime-$_.CreationTime}; Ascending=$false}}}).TotalMilliseconds



592.3512

 Result: Second command is 8.2% faster

 

Test #3  

PS > (measure-Command { 1..10 | foreach { dir | sort -unique | select name}}).TotalMilliseconds

6405.653


PS > (measure-Command { 1..10 | foreach { dir | select name | sort -unique}}).TotalMilliseconds

750.8251


Result: Second command is 753% faster!

 

The reason why 'select then sort' is faster to execute is because there are much less properties for sort-object to work on. When you select certain properties from a collection, select-object creates a new object with just the specified properties of the incoming object thus resulting in a smaller object to process.

One thing is for sure: In most cases, select objects before sorting them, and ALWAYS make sure they produce the SAME output!.