Flying to NYC
I'll be spending the nest 10 days in our company's web farm in NYC.
Its going to be an 11 hours flight from Israel to NY :-(
I'm going to install some new web servers and 2 load balancers.
See ya next week, or so :-)
If you repeat it [$CRIPT] it!
I'll be spending the nest 10 days in our company's web farm in NYC.
Its going to be an 11 hours flight from Israel to NY :-(
I'm going to install some new web servers and 2 load balancers.
See ya next week, or so :-)
Posted by
Shay Levy
at
9/27/2007 07:09:00 PM
1 comments
 
 
"Get-Databases" function creates a custom "view" of some database properties on the specified SQL server.
function Get-SQLDatabases{
    param(
        [string]$server=$(throw "Please specify SQL server name.")
    )  
    [void][reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo")
    $smo = new-object Microsoft.SqlServer.Management.Smo.Server $server
    $count=0;  
    $smo.databases | foreach {
        $db = $smo.databases[$_.name];
        $obj = new-object psobject;
        add-member -inp $obj NoteProperty "#" ($count+1);
        add-member -inp $obj NoteProperty "Server" ([string][regex]::replace($db.Parent,"\[|\]","")).toupper();
        add-member -inp $obj NoteProperty "DB Name" $db.Name;
        add-member -inp $obj NoteProperty "ID" $db.id;
        add-member -inp $obj NoteProperty "Size(MB)" $db.size.tostring("N2"); 
        add-member -inp $obj NoteProperty "Free(MB)" ($db.SpaceAvailable/1024).tostring("N2") ; 
        add-member -inp $obj NoteProperty "Status" $db.Status; 
        add-member -inp $obj NoteProperty "Last Backup" $db.LastBackupDate;
        add-member -inp $obj NoteProperty "SystemDB" $db.IsSystemObject;
        $obj;
        $count++
    }
} 
PS > Get-SQLDatabases shayl\sqlexpress | format-table -autosize 
# Server                     DB Name ID Size(MB) Free(MB) Status  Last Backup               SystemDB
- ------                       -------      -- --------    --------    ------    -----------                   --------
1 SHAYL\SQLEXPRESS master    1  6.75       1.44        Normal  01/01/0001 00:00:00  True
2 SHAYL\SQLEXPRESS model     3  3.19       1.08        Normal  01/01/0001 00:00:00  True
3 SHAYL\SQLEXPRESS msdb      4  9.44       2.00        Normal  01/01/0001 00:00:00  True
4 SHAYL\SQLEXPRESS tempdb   2  2.69      1.03         Normal  01/01/0001 00:00:00  True
5 SHAYL\SQLEXPRESS test        5  7.13       0.20        Normal  01/01/0001 00:00:00  False
Posted by
Shay Levy
at
9/20/2007 12:55:00 PM
1 comments
 
 
Labels: PowerShell, SMO, SQL
The "New-DummyTree" function creates a directory tree duplicate. The new directory tree will be an exact copy of the source directory, including file names and there's date attributes, only files will be 0 bytes long. Then you can test your scripting scenarios on its structure.
I used it only once when I tested a mass file processing activity (copy, delete, rename, archive (with New-RarArchive) and so on. 
I couldn't test it against the real directory tree since it was based on the files date attributes, not to mention that the source files were very big in size, and I wanted to test the script as one piece and not just part of it in separate files.  
It also demonstrates how you can alter a file or directory date attributes, such as LastWriteTime, etc.
So, for what it's worth...
function New-DummyTree{
    
   param(
        [string]$source=$(throw "Invalid source directory path"),
        [string]$destination
    )
    if( -not (Test-Path $source -pathType container)){
        write-error "Invalid source directory path: <$source>";
        break;
    }
    
    get-childitem $source -recurse | where {-not $_.psiscontainer} | foreach {
        $path="{0}{1}" -f $destination,$($_.directoryname.remove(0,$source.length));
        $file=new-item -path $path -name $_.name -type file -force;
        $file.CreationTime=$_.CreationTime;
        $file.LastWriteTime=$_.LastWriteTime;
        $file.LastAccessTime=$_.LastAccessTime;
    }
    #set-location $destination
}
Note, You don't need to create the destination directory, It will be created on the fly if it doesn't exist. 
 
Usage:
New-DummyTree <SourcePath> <DestinationPath>
Posted by
Shay Levy
at
9/20/2007 01:07:00 AM
0
comments
 
 
Labels: PowerShell
There has been some talking on the Windows PowerShell in Action  Manning forum about a new PowerShell  book titled "Windows Powershell in Practice". Windows PowerShell in Action by Bruce Payette was fantastic. Personally, it was and still my PowerShell bible. I'm sure the new companion book will be as exciting as its big brother ;-)
Bruce comments when asked when the book will release:
"Windows PowerShell in Practice" is a new book that is in development at Manning. I'm not sure when it will be available. It will cover things like the PowerShell SDK (writing cmdlets, providers, embedding the PowerShell engine in other applications, etc.) as well as larger, more domain specific examples and advance scripting techniques. 
I'm not currently a direct contributor (but I do kibitz on occasion.) Jim Truher (who co-designed the language with me) and MOW are working on this book. I'll ping them and see how it's going...
-bruce 
Posted by
Shay Levy
at
9/19/2007 10:28:00 PM
0
comments
 
 
Labels: books, PowerShell
function New-RarArchive{
    param(
        [string] $source=$(throw "Invalid source parameter"),    
        [string] $destination=$(throw "Invalid destination parameter"),    
        [string] $name=$(throw "Invalid name parameter"),
        [string] $winrar = "$env:ProgramFiles\WinRAR\WinRAR.exe",
        [switch] $directory
    )  
    if($directory){
        if( -not (Test-Path $source -pathType container)){
            write-error "Invalid directory path <$source>";
            break;
         } 
   } else {
        if( -not (Test-Path $source -pathType leaf)){
            write-error "Invalid file path <$source>";
            break;
        }
    }
    if( -not (Test-Path $destination -pathType container)){
        write-error "Invalid destination path <$destination>";
        break;
    } 
    # winrar switches:
    # A - Add specified files and folders to an archive.
    # IBCK -  Minimize WinRAR to tray, runs in the background.
    # Y - Yes will be the default and automatic reply to all queries.
    # R - recurse subfolders.    
    # ILOG[name] - log errors to file  
    if($directory){
        & $winrar A -IBCK -Y -R "$destination\$name" $("$source\*.*") | out-null
    } else {
        & $winrar A -IBCK -Y -R "$destination\$name" $source | out-null
    }
    if($LASTEXITCODE -match "[01]"){
        # 0 - Successful operation.
        # 1 - Warning. Non fatal error(s) occurred.
        write-host "New archive created <$destination\$name>" -foreground green
        $true;
    } else {
        switch($LASTEXITCODE){
            2       {write-error "A fatal error occurred."}
            3       {write-error "CRC error occurred when unpacking."}
            4       {write-error "Attempt to modify a locked archive."}
            5       {write-error "Write error."}
            6       {write-error "File open error."}
            7       {write-error "Wrong command line option."}
            8       {write-error "Not enough memory."}
            9       {write-error "File create error."}
            255    {write-error "User break."}
        }
        $false;
    }
}  
Archive c:\scripts directory to \\server\share
>> New-RarArchive -source "c:\scripts" -destination \\server\share -name "test.rar" -directory
Archive a file
>> New-RarArchive -source "C:\Scripts\test.exe" -destination "D:\Backup" -name "test.rar"
WinRAR -ibkp switch adds a visual indicator in the windows system tray.
Posted by
Shay Levy
at
9/17/2007 10:49:00 AM
2
comments
 
 
Labels: PowerShell
Remember the old MS-DOS choice command? It prompts the user to make a choice in a batch program by displaying a prompt and pausing for the user to choose from a set of user-option keys. 
In PowerShell, you can provide the same mechanism with .NET built-in classes without the need for external files. You can see this method in action on every cmdlet declared with -confirm parameter.
PS > Get-Process s* | Stop-Process -confirm
Confirm
Are you sure you want to perform this action?
Performing operation "Stop-Process" on Target "services (520)".
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "Y"):  
The user is presented with "plain old message box kind" prompt, built from a caption, message and number of choices to choose from: 
 
Confirm = Caption
Are you sure you want to... = Message  
And the choices:
[Y] Yes
[A] Yes to All
[N] No
[L] No to All
[S] Suspend  
In my scripts I used to build this mechanism manually and write to the host the caption/message and choices until I 'found' this while digging on Mighty MoW's PowerTab scripts. The method is also described on MSDN PSHostUserInterface.PromptForChoice. 
 
PS > $host.ui | gm
TypeName: System.Management.Automation.Internal.Host.InternalHostUserInterface
Name                          MemberType
----                             ----------
...
Prompt                        Method
PromptForChoice         Method
PromptForCredential    Method
...  
The definition for PromptForChoice is:
System.Int32 PromptForChoice(String caption, String message, Collection`1 choices, Int32 defaultChoice)  
So, how can you implement it in your scripts? Here is my variation:
$caption = "Confirm";
$message = "Are you sure?";
$yes = new-Object System.Management.Automation.Host.ChoiceDescription "&Yes","help";
$no = new-Object System.Management.Automation.Host.ChoiceDescription "&No","help";
$choices = [System.Management.Automation.Host.ChoiceDescription[]]($yes,$no);
$answer = $host.ui.PromptForChoice($caption,$message,$choices,0) 
switch ($answer){
    0 {"You entered 0"; break}
    1 {"You entered 1"; break}
}  
write-host "Rest of script goes here..."
Here is the output:
PS C:\Scripts> .\PromptForChoice.ps1 
Confirm
Are you sure?
[Y] Yes  [N] No  [?] Help (default is "Y"): n
You entered 1
Rest of script goes here...
PS >
Note that the special character "&" (ampersand) might be embedded in the label string to indicate that the next character is a "hot key" (for example, "Yes to &All"). The hot key allows the user to quickly set the input focus to this choice.
The default choice is determined by the order/index of the collection variables ($choices). To indicate no default, set defaultChoice to -1: 
$choices = [System.Management.Automation.Host.ChoiceDescription[]]($yes,$no);
$yes = 0
$no = 1  
 
 
There is also the "Help" option, which we didn't explicitly define. 
The strings "help" in the $yes and $no variables are the help text to display when the user types "?"
$no = new-Object System.Management.Automation.Host.ChoiceDescription "&No","help";
I also wanted to implement the Suspend feature. Suspending the process is totally awesome. You have another chance to pause operation and get up to date, verified information, before proceeding. I knew that there is something called "Nested Prompt" and something inside felt that this is the place where it might be used. So I made some tests and here's the code with Suspend.
$caption = "Confirm";
$message = "Are you sure?";
$yes = new-Object System.Management.Automation.Host.ChoiceDescription "&Yes","help";
$no = new-Object System.Management.Automation.Host.ChoiceDescription "&No","help";
$Suspend = new-Object System.Management.Automation.Host.ChoiceDescription "&Suspend","help";
$choices = [System.Management.Automation.Host.ChoiceDescription[]]($yes,$no,$suspend);
$Answer = $host.ui.PromptForChoice($caption,$message,$Choices,0) 
switch ($Answer){
    2 {"You entered 2, entering nested prompt, type exit to return"; $Host.EnterNestedPrompt()}    
}  
write-host "Rest of script goes here..."
Here is the output:
PS C:\Scripts> .\PromptForChoice.ps1
Confirm
Are you sure?
[Y] Yes  [N] No  [S] Suspend  [?] Help (default is "Y"): s
You entered 2, entering nested prompt, type exit to return
PS >>> exit
Rest of script goes here...
PS >  
Note that the PowerShell prompt is visually changing, colored in yellow ( adding >> to the default prompt) indicating that you're inside a nested prompt. To exit nested prompts simply type exit. 
Posted by
Shay Levy
at
9/16/2007 10:34:00 PM
2
comments
 
 
Labels: PowerShell, prompt
New complete eBook : The Shortcut Guide to Exchange Server 2007 Storage Systems, by Jim McBee, is available for download on Realtime Publishers website. This web site is a great resource of free eBooks covering all aspects of IT. Register now and download it.
Here's the description for this title: 
The conventional way of planning for Exchange Server storage is to throw a lot of disk storage at the server and hope that is sufficient. Mail storage requirements continue to grow for even average users; these users place more and more capacity requirements not only on disk storage but also on disk I/O capacity. As current capacity requirements are exceeded, the storage system must provide scalability. The Shortcut Guide to Exchange Server 2007 Storage Systems, authored by Microsoft Exchange MVP Jim McBee, covers Exchange Server storage capacity requirement planning, the basics of using iSCSI SANs, and best practices for scalability and SAN operations.
Posted by
Shay Levy
at
9/16/2007 08:08:00 AM
0
comments
 
 
<a href="city.html?n=110">Jerusalem</a> *</td><td class="r">Sat 5:44 PM</td>
 
Based on that line we can build a regular expression to match each place and its local time (yellowed text).
 
Regex break through:
'href="city.html\?n=\d+">(?<place>[^/]*)</a>\s?\*?</td><td class="r">(?<time>[^/]*)</td>'
Starts with href="city.html
Followed by ?n=  (The ? sign is a meta character so escape it, \?n=)
Followed by one or more digits \d+"> with a quote and a closing tag bracket (110)
Followed by (?<place>[^/]*) (equals to Jerusalem, match and capture)
Followed by closing a tag </a>, and (?:\s\*)? (optional space and *, don't insert into $matches)
Followed by </td><td class="r">
Followed by (?<time>[^/]*) (equals to Sat 5:44 PM, match and capture)
Followed by </td>
Captures legend:
(exp)               Match exp and capture it in an automatically numbered group 
(?<name>exp)  Match exp and capture it in a group named name 
(?:exp)            Match exp, but do not capture it 
 
#####################################
function Get-WorldClock{
    param (
        [string]$continent="",
        [string]$filter="*"
    )
    
$baseurl = http://www.timeanddate.com/worldclock/
# define values and shortcuts for -continent parameter
switch($continent){
    "as"                {$url+="$baseurl/custom.html?continent=asia"; break}
    "asia"             {$url+="$baseurl/custom.html?continent=asia"; break}
    "af"                {$url+="$baseurl/custom.html?continent=africa"; break}
    "africa"           {$url+="$baseurl/custom.html?continent=africa"; break}
    "na"                {$url+="$baseurl/custom.html?continent=namerica"; break}
    "namerica"      {$url+="$baseurl/custom.html?continent=namerica"; break}
    "sa"                {$url+="$baseurl/custom.html?continent=samerica"; break}
    "samerica"       {$url+="$baseurl/custom.html?continent=samerica"; break}
    "au"                {$url+="$baseurl/custom.html?continent=australasia"; break}
    "australasia"    {$url+="$baseurl/custom.html?continent=australasia"; break}
    "pa"                {$url+="$baseurl/custom.html?continent=australasia"; break}
    "pacific"          {$url+="$baseurl/custom.html?continent=australasia"; break}
    "eu"                {$url+="$baseurl/custom.html?continent=europe"; break}
    "europe"          {$url+="$baseurl/custom.html?continent=europe"; break}
    default            {$url=$baseurl; break}
}  
trap{throw "Error: Can't connect to $url`n $_"; break}
    $wc=(new-object net.webclient).DownloadString($url);
    $regex=([regex]href="city.html\?n=\d+">(?<place>[^/]*)</a>(?:\s\*)?</td><td class="r">(?<time>[^/]*)</td>').matches($wc);
    
$times = $regex | select  @{n="Place";e={$_.groups['place'].value}}, @{n="Time";e={$_.groups['time'].value}}
    
if($filter -eq "*"){
        $times | sort place | format-table -autosize
    } else {
        $times | where {$_.place -like "*$filter*"} | sort place | format-table -autosize
    }
}
#################
You can also download the script file from here.
Examples:
1. Current local times around the world (Main list)
PS > Get-WorldClock
Place               Time
-----                ----
Addis Ababa    Sat 6:01 PM
Adelaide         Sun 12:31 AM
Aden              Sat 6:01 PM
Algiers           Sat 4:01 PM
Amman          Sat 6:01 PM
Amsterdam     Sat 5:01 PM
Anadyr           Sun 4:01 AM
Anchorage      Sat 7:01 AM
Ankara           Sat 6:01 PM
Antananarivo   Sat 6:01 PM
Asuncion         Sat 11:01 AM
Athens            Sat 6:01 PM
Atlanta           Sat 11:01 AM
Auckland        Sun 3:01 AM
...
...  
2. Current local times in Europe (eu or europe)
PS > Get-WorldClock -continent eu
...
...
Beijing            Sat 11:32 PM
Beirut              Sat 6:32 PM
Belgrade          Sat 5:32 PM
Berlin              Sat 5:32 PM
Bogota            Sat 10:32 AM
Boston            Sat 11:32 AM
Brasilia           Sat 12:32 PM
Brisbane          Sun 1:32 AM
Brussels           Sat 5:32 PM
Bucharest        Sat 6:32 PM
Budapest         Sat 5:32 PM
Buenos Aires   Sat 12:32 PM
...
...  
2. Current local time in Jerusalem (Asia)
PS > Get-WorldClock -continent asia -filter jeru
Place           Time
-----            ----
Jerusalem   Sat 6:42 PM
Posted by
Shay Levy
at
9/15/2007 06:00:00 PM
2
comments
 
 
Labels: PowerShell
I removed some definition columns for readability. During Get-Command exploration I found some interesting things on my environment. Check yours :-)
To get a cmdlet syntax, not so readable
PS > get-command get-childitem -syntax
Get-ChildItem [[-Path] <String[]>] [[-Filter] <String>] [-Include <String[]>] [-Exclude <String[]>] [-Recurse] [-Force] [-Name] [-Verbose]
[-Debug] [-ErrorAction <ActionPreference>] [-ErrorVariable <String>] [-OutVariable <String>] [-OutBuffer <Int32>]
Get-ChildItem [-LiteralPath] <String[]> [[-Filter] <String>] [-Include <String[]>] [-Exclude <String[]>] [-Recurse] [-Force] [-Name] [-Verb
ose] [-Debug] [-ErrorAction <ActionPreference>] [-ErrorVariable <String>] [-OutVariable <String>] [-OutBuffer <Int32>]  
Same goes here . It is better to run "get-help cmdlet-name -full"
 
PS C:\Scripts> get-command get-childitem -definition
CommandType  Name                     Definition
-----------          ----                        ----------
Cmdlet              Get-ChildItem         Get-ChildItem [[-Path] <String[]>] [[-Filter] <String>] [-Include <String[]>] [-Exclude <String[]>] [-Recurse]...  
Get the most popular cmdlets by verb. And the winner is...
PS > get-command | group verb
Count Name
----- ----
  134 Get
   87 Set
   60 Remove
   49 New
   17 Enable
   16 Add
   15 Disable
   15 Test
   11 Update
   10 Export
    8 Move
    7 Write
    6 Out
    6 Start
    5 Stop
    5 Suspend
    5 Resume
    5 Clear
    5 Import
    4 Format
    3 Copy
    ...
    ...  
List commands were "email" appears in the command noun part
PS > get-command -noun *email*
CommandType     Name
-----------             ----
Cmdlet                 Get-EmailAddressPolicy
Cmdlet                 New-EmailAddressPolicy
Cmdlet                 Remove-EmailAddressPolicy
Cmdlet                 Set-EmailAddressPolicy
Cmdlet                 Update-EmailAddressPolicy  
The -commandType property can take one (or more of this values)
    Alias
    Cmdlet 
    ExternalScript
    Function 
    Filter
    Application
    Script
    All  
So, get all registered filters
PS > get-command -commandType Filter
CommandType Name                       Definition
-----------         ----                          ----------
Function          A:                            Set-Location A:
Function          B:                            Set-Location B:
Function          backup-profile          copy-item $PROFILE "C:\Scripts\PoSH Profile" -force;...
Function          C:                            Set-Location C:
Function          Clear-Host                $spaceType = [System.Management.Automation...
Function          Clear-Temp              remove-item -r -fo $env:temp\* -ea 0;...
Function          D:                            Set-Location D:
Function          e                              & "explorer.exe" $args[0];
Function          E:                             Set-Location E:
Function        echo-args                   for($i=0;$i -lt $args.length;$i++){...
Function        edit-profile                 & $textpad $PROFILE;
Function        F:                               Set-Location F:
Function        G:                                Set-Location G:
Function        get-def                        ($args[0] | gm $args[1]).definition.split(',');...
Function        Get-Params                  param(...
Function        Get-RemoteEventLog    [System.Diagnostics.Eventlog]::GetEventLogs(...
Function        Get-RemoteProcess      [System.Diagnostics.Process]::GetProcesses(...
Function        Get-RemoteService       [void][System.Reflection.Assembly]::LoadWithPartial...
...
...  
To return all scripts that are found in your PATH environment variable. Interesting ... I installed the Exchange 2007 management pack and it registered some scripts:
PS > get-command -commandType ExternalScript
CommandType    Name                                   
-----------            ----                                   
ExternalScript     AddReplicaToPFRecursive.ps1            
ExternalScript     AddUsersToPFRecursive.ps1              
ExternalScript     CheckInvalidRecipients.ps1             
ExternalScript     ConfigureAdam.ps1                      
ExternalScript     configure-SMBIPsec.ps1                 
ExternalScript     enable-CrossForestConnector.ps1        
ExternalScript     Exchange.ps1                           
...
...  
-CommandType can also get multiple types, separated by a comma
PS C:\Scripts> Get-Command -commandType Filter,ExternalScript
CommandType     Name
-----------             ----
Function              A:
ExternalScript     AddReplicaToPFRecursive.ps1
ExternalScript     AddUsersToPFRecursive.ps1
Function             B:
Function             backup-profile
Function            C:
ExternalScript    CheckInvalidRecipients.ps1
Function           Clear-Host
Function           Clear-Temp
ExternalScript   ConfigureAdam.ps1
ExternalScript  configure-SMBIPsec.ps1
Function          D:
Function          e
Function          E:
Function          echo-args
...
... 
Now, Get ExternalScript file paths:
PS > get-command -commandType ExternalScript | foreach {$_.path}
C:\Program Files\Microsoft\Exchange Server\Scripts\AddReplicaToPFRecursive.ps1
C:\Program Files\Microsoft\Exchange Server\Scripts\AddUsersToPFRecursive.ps1
C:\Program Files\Microsoft\Exchange Server\Scripts\CheckInvalidRecipients.ps1
C:\Program Files\Microsoft\Exchange Server\Scripts\ConfigureAdam.ps1
C:\Program Files\Microsoft\Exchange Server\Scripts\configure-SMBIPsec.ps1
...
...  
To add your own scripts directory type (e.g., c:\scripts)
PS > $env:path+=";c:\scripts"
Now you can execute all scripts in your scripts directory, typing only its name (with/out .ps1 extension) and you don't need to be in the scripts working directory. I'll introduce Get-WorldClock on my next blog post :-)
PS D:\> Get-WorldClock
Place                  Time
-----                   ----
Addis Ababa       Sat 4:19 PM
Adelaide            Sat 10:49 PM
Aden                 Sat 4:19 PM
Algiers              Sat 2:19 PM
Amman             Sat 4:19 PM
Amsterdam       Sat 3:19 PM
Anadyr              Sun 2:19 AM
Anchorage        Sat 5:19 AM
Ankara             Sat 4:19 PM
Antananarivo    Sat 4:19 PM
Asuncion           Sat 9:19 AM
Athens              Sat 4:19 PM
Atlanta             Sat 9:19 AM
Auckland          Sun 1:19 AM
...
...  
Group all commndlets by its PSSnapIn property 
 
PS > get-command | where {$_.CommandType -eq "Cmdlet"} | group PSSnapIn | select count,name
Count  Name
-----    ----
  381   Microsoft.Exchange.Management.PowerShell.Admin
   47   Microsoft.PowerShell.Management
   12   Microsoft.PowerShell.Core
   58   Microsoft.PowerShell.Utility
   10   Microsoft.PowerShell.Security
    2   Microsoft.PowerShell.Host  
Another way to list only Exchange 2007 command-lets
PS > get-command | where {$_.PSSnapIn.name -match "exchange"}
CommandType     Name
-----------             ----
Cmdlet                Add-ADPermission
Cmdlet                Add-AvailabilityAddressSpace
Cmdlet                Add-ContentFilterPhrase
Cmdlet                Add-DistributionGroupMember
Cmdlet                Add-ExchangeAdministrator
Cmdlet                Add-IPAllowListEntry
Cmdlet                Add-IPAllowListProvider
Cmdlet               Add-IPBlockListEntry
Cmdlet               Add-IPBlockListProvider
Cmdlet               Add-MailboxPermission
...
...  
Or even better, filter with the pssnapin parameter
PS > get-command -pssnapin Microsoft.Exchange.Management.PowerShell.Admin
CommandType     Name
-----------             ----
Cmdlet          Add-ADPermission
Cmdlet          Add-AvailabilityAddressSpace
Cmdlet          Add-ContentFilterPhrase
Cmdlet          Add-DistributionGroupMember
Cmdlet          Add-ExchangeAdministrator
Cmdlet          Add-IPAllowListEntry
Cmdlet          Add-IPAllowListProvider
Cmdlet          Add-IPBlockListEntry
Cmdlet          Add-IPBlockListProvider
Cmdlet          Add-MailboxPermission
...
...  
Get all properties for a command-let
PS > (get-command select-string).parametersets[0].parameters | select name,ParameterType,aliases
Name               ParameterType                                                     Aliases
----                   -------------                                                          -------
InputObject       System.Management.Automation.PSObject              {}
Pattern             System.String[]                                                       {}
SimpleMatch     System.Management.Automation.SwitchParameter   {}
CaseSensitive   System.Management.Automation.SwitchParameter   {}
Quiet               System.Management.Automation.SwitchParameter   {}
List                  System.Management.Automation.SwitchParameter   {}
Include             System.String[]                                                       {}
Exclude            System.String[]                                                       {}
Verbose           System.Management.Automation.SwitchParameter   {vb}
Debug              System.Management.Automation.SwitchParameter  {db}
ErrorAction      System.Management.Automation.ActionPreference  {ea}
ErrorVariable    System.String                                                         {ev}
OutVariable      System.String                                                         {ov}
OutBuffer         System.Int32                                                          {ob}  
I also wrote a function Get-Params which takes a cmdlet name and calculates the
shortest alias name for each cmdlet parameter. Very useful when typing commands interactively. It also emits some additional important columns.  
>> Get-Params select-string
-----------------
- select-string -
-----------------  
Name               Alias        Position     Type
----                  -----         --------       ----
caseSensitive   -c            named        SwitchParameter
exclude            -e            named        string[]
include             -inc         named        string[]
inputObject      -inp        named         psobject
list                   -l           named         SwitchParameter
path                 -path      2                string[]
pattern             -patt      1                string[]
quiet                -q          named        SwitchParameter
simpleMatch     -s          named        SwitchParameter
text                  -t          2                string[] 
Posted by
Shay Levy
at
9/15/2007 04:32:00 PM
0
comments
 
 
Labels: PowerShell
There has been a lot of questions in the PowerShell news group regarding aged files. To simplify the search process I wrote the "Get-AgedFiles" function. It's simple to use and also pipeline friendly :-)
 
Get-AgedFiles searches for aged files based on this parameters:
-path, String, starting directory path ,wildcards supported (e.g., c:\scripts\*.ps1) 
-age, Integer, file age , default value: 1.
-timePart, String,  can be one of this shortcuts values, default value "d":
    y     = Years
    m    = Months
    d     = Days
    h     = Hours
    mm = Minutes
    s     = seconds
    t     = Ticks 
 
-property, String, The file property for dates comparison , default value "LastWriteTime":
    CreationTime
    CreationTimeUtc
    LastAccessTime
    LastAccessTimeUtc
    LastWriteTime
    LastWriteTimeUtc     
-recurse, switch parameter, when declared, performs the search on sub directories.
//TODO:
Add support to get-childitem's include,exclude,filter parameters. 
Usage:
 
# Get all files from <D:\Backup>, 1 day old (only -path is required) based on <LastWriteTime> property
>> Get-AgedFiles -path "D:\Backup"
# Get all *.bkp files  from <D:\SQLBackup\*.bkp> 10 Days old based on <LastWriteTime> property
>> Get-AgedFiles -path "D:\SQLBackup\*.bkp" -age 10 -timePart d  
# Get all files, recursively, from <c:\scripts> 6 Months old based on <CreationTime> property
>> Get-AgedFiles -path "c:\scripts" -age 6 -timePart m -property CreationTime -recurse  
# Get all files from current directory, 7 Days old based on <LastWriteTime> property
# delete all 
>> Get-AgedFiles . 7 d | remove-item -whatif  
# Get all files ,recursively, from current directory, 1 Year old based on <LastWriteTime> 
# property, move all to c:\scripts\temp
>> Get-AgedFiles . 1 y -recurse | move-item -destination c:\scripts\temp -whatif  
The function file is also available for download here.
######################################
function Get-AgedFiles{
    param(
        [string]$path=$(throw "needs a path"),            
        [int]$age=1,
        [string]$timePart="TotalDays",
        [string]$property="LastWriteTime",
        [switch]$recurse    
    )  
    switch ($timePart){
        "y"    {$timePart="TotalDays"; $age*=365 ; break}
        "m"    {$timePart="TotalDays"; $age*=30 ; break}
        "d"    {$timePart="TotalDays"; break}
        "h"    {$timePart="TotalHours"; break}
        "mm"  {$timePart="TotalMinutes"; break}
        "s"     {$timePart="TotalSeconds"; break}
        "t"     {$timePart="Ticks"; break}
    }  
    if($recurse){
        get-childitem $path -recurse | where {
           !$_.psiscontainer -and ((get-date).subtract($_.$property).$timePart -ge $age)
        }    
    } else {
        get-childitem $path | where {
           !$_.psiscontainer -and ((get-date).subtract($_.$property).$timePart -ge $age)
        }            
    }  
}
########################
Posted by
Shay Levy
at
9/13/2007 06:14:00 PM
0
comments
 
 
Labels: PowerShell, search
Sapien technologies just released a com DLL to support simple FTP transfers. It supports the get/put FTP verbs, and I already tested them successfully. Its free to use and can be downloaded from Sapien's website. Thanks Sapien!
The download file includes two VBScripts files, one for upload and one for downloads. Here's a simple conversion to PowerShell.
Before starting using the functions, read the readme file, copy the DLL to system32 directory and register it:
regsvr32.exe ftp.dll
Cool, lets start
###############3
function Get-FTPFile{
    param(
        [string]$url,
        [string]$port=21,
        [string]$user,
        [string]$pass,
        [string]$RemoteFilePath,
        [string]$localPath
    ) 
    $ftp = new-object -com Primalscript.FTPTransfer;
    $ftp.Passive = 1;
    $ftp.port = $port;  
    if($ftp.Connect($url,$user,$pass) -eq 0){
        "Can't connect. " + $ftp.Status;
    } else {
        "Starting download"
        If($ftp.Get($RemoteFilePath,$localPath) -eq 0){
            "Error downloading file " + $ftp.Status;
        } Else {
            "Download complete";
        }
        $ftp.Disconnect();
    }
}  
Usage:
Get-FTPFile <ftpUrl> <port> <username> <password> <RemoteFilePath> <localDonloadPath>
############################
function Put-FTPFile{
    param(
        [string]$url,
        [string]$port=21,
        [string]$user,
        [string]$pass,
        [string]$localFile,
        [string]$RemotePath
    )  
    $ftp = new-object -com Primalscript.FTPTransfer;
    $ftp.Passive = 1;
    $ftp.port = $port;  
    if($ftp.Connect($url,$user,$pass) -eq 0){
        "Can't connect. " + $ftp.Status;
    } else {
        if($ftp.Put($RemotePath,$localFile) -eq 1){
            "success upload";            
        } else {
            "Error uploading file. " +$ftp.Status;
        }
        $ftp.Disconnect();
    }
}  
Usage:
Get-FTPFile <ftpUrl> <port> <username> <password> <localUploadFile> <RemoteUploadPath>
##############
I'm maybe missing something, but I noticed when using the Put-FTPFile that even if the upload was successful, Put() returns 1 (error???) instead of 0. I commented about it in Spain's website FTP tool page.
UPDATE 09/19/2007:
Here's Don Jones reply:
0 is bad, 1 is good news.
1 = success (C++ TRUE)
0 = failure (C++ FALSE)  
After all, I did miss something :-)
Thanks Don.
Posted by
Shay Levy
at
9/13/2007 04:06:00 PM
13
comments
 
 
Labels: automate, ftp, PowerShell
Posted by
Shay Levy
at
9/12/2007 02:28:00 PM
0
comments
 
 
Labels: PowerShell, remoting
Scott Hanselman recorded another PowerShell introduction video on dnrTV!.
In the video you can see how to install and use MoW's super cool PowerTab and some other stuff like loading DLL and .NET classes along with basic PowerShell.
The video can be downloaded (~180MB).
Posted by
Shay Levy
at
9/12/2007 02:03:00 PM
0
comments
 
 
Labels: PowerShell, video
I released this scripts about a week ago, in respond to a discussion in the Windows PowerShell news group. The goal is to read a script content and replace all command-let names to there alias's and vice versa.
The two functions below takes a script file path as the argument and convert it respectively.  
The first function, "Convert-CmdletToAlias", is more *secure* to use as it search for all cmdlet names (which doesn't contain non special chars) and replaces each one it finds with the first corresponding alias (there can be more than one).
The second function, "Convert-AliasToCmdlet", is more *dangerous*. Richard Siddaway reported that there is one major draw back. If you used the "%" sign as an alias for the foreach-object cmdlet, things may go wrong and behave unexpectedly. The reason is that "%" is also the symbol for modulo.
Keith hill suggested to parse the script before the final conversion. Didn't find a way so far so any suggestions/modifications are welcomed.
#### EDIT (11/01/07)  #####
Check out Keith's post on parsing the script for errors prior to executing it 
PowerShell QuickTip: Preparsing Scripts to Check for Syntax Errors
#########################
Anyway, the conversion is not written back to the script file and only displayed back to the console. If you decide to use the functions, make sure to create a backup copy of the original scripts and always test the final converted script before using it in production.
Usage:
Convert-CmdletToAlias <filepath.ps1>
Convert-AliasToCmdlet <filepath.ps1>  
###############################
function Convert-CmdletToAlias{
    param([string]$filepath)
    if(!(test-path $filepath)){
        write-warning "Error: File doesnt exist";
        break;
    }
    $src = [System.IO.File]::ReadAllText($filepath);
    $cmdlets = get-command | where {$_.CommandType -eq "Cmdlet"} | select name
    $cmdlets | foreach {  
$cmd = $_.name;
        if($src -match "\b$cmd\b") {
            $alias = @(get-alias | where {$_.definition -eq $cmd});    
            $src=$src -replace($cmd,$alias[0]);
        }
    }
    $src;
}  
#####################
function Convert-AliasToCmdlet{
    param([string]$filepath)
    if(!(test-path $filepath)) {
        write-warning "Error: File doesnt exist";
        break;
    }
    #cls
    $src = [System.IO.File]::ReadAllText($filepath);
    $aliases = get-alias | select Name,Definition  
$aliases | foreach {
        trap{write-host "ERROR cant process alias: <$alias> -f red -b black"; continue}
        $alias = @($_)[0];
        $regex=[regex]::escape($alias.name);
        # for some reason this is not working "\b" +$regex +"\b"
        if($src -match "\s" +$regex +"\s"){
            $src=$src -replace($regex,$alias.definition);
        }
    }
    $src;        
}   
Posted by
Shay Levy
at
9/09/2007 10:04:00 AM
0
comments
 
 
Labels: convert, functions, PowerShell
There are two major differences between functions and filters in PowerShell: 
Both procedures can be used in pipelines. 
When a function is used, the special variable $input is available to process through the input collection. For filters, the special variable $_ contains the current pipeline object. 
Filter, as its name suggests will pass on only certain objects down the pipeline.
To demonstrate it, here are two filters to help where IP address are involved.  
I have a text file were each line contains an IP address.
###### ip.txt #####
10.0.0.138
1.1.1.1111
192.168.2.1
10.0.0.101
10.0.0.102
10.0.0.103  
###### EOF #######
I want to get the content of this file and operate ONLY on live hosts.
The first filter will validate the IP address and stream down the pipe only valid ones.
The second filter will ping each valid host passed and test its availability,.
The third, ForEach cmdlet,  will run some code on the filtered IPs.  
filter Validate-IPAddress {
    trap{write-host "$_ <$input>" -f red -b black; continue;}    
    [System.Net.IPAddress]::Parse($_).IPAddressToString;    
}  
filter Ping-Host{
    begin{
        # instantiate once for all piped objects
        $ping = new-object System.Net.NetworkInformation.Ping;
    }
    process{    
        # ping test
        $stat=$ping.Send($_).status;
        if($stat -ne "Success"){write-warning "$_ is not available <$stat>";} 
        else {$_;}
    }    
}  
# cat = Get-Content
# -f = foreground
# -b = background
cat ip.txt | Validate-IPAddress | Ping-Host | foreach {    
    write-host "$_ is ALIVE, run some code" -f green -b black
} 
# colored output , just for demonstrating
10.0.0.138 is ALIVE, run some code
An invalid IP address was specified. <1.1.1.1111>
WARNING: 192.168.2.1 is not available <TimedOut>
10.0.0.101 is ALIVE, run some code
WARNING: 10.0.0.102 is not available <TimedOut>
10.0.0.103 is ALIVE, run some code  
################################################
Here's the filters final version. You can see that only validated IPs and live hosts are processed.
filter Validate-IPAddress {
    trap{continue;}    
    [System.Net.IPAddress]::Parse($_).IPAddressToString;
}  
filter Ping-Host{
    begin{ $ping = new-object System.Net.NetworkInformation.Ping; }
    process{ if($ping.Send($_).status -eq "Success") {$_;} }    
}  
cat ip.txt | Validate-IPAddress | Ping-Host | foreach {
    write-host "$_ is ALIVE, run some code" -f green -b black
} 
# output
10.0.0.138 is ALIVE, run some code
10.0.0.101 is ALIVE, run some code
10.0.0.103 is ALIVE, run some code 
Posted by
Shay Levy
at
9/07/2007 05:34:00 PM
2
comments
 
 
Labels: filters, functions, ip, PowerShell, validation
Does the installation tampers PowerShell core files? Why? What's wrong?  
I restarted PowerShell and the error showed up again, Hmm.. I need to find out what went wrong, which cmdlet deals with execution restrictions...ahhhh...hmmm...right... 
Get-ExecutionPolicy!  So I run it:
 
PS C:\Scripts> Get-ExecutionPolicy
AllSigned  
It seems that the SDK setup process reverts PowerShell excecution policy back to its default "out-of-the-box" state - AllSigned, which means only scripts that were digitally signed can execute. 
 
PS C:\Scripts> Set-ExecutionPolicy RemoteSigned
PS C:\Scripts> 
 
Restarted, and the message has gone.
Posted by
Shay Levy
at
9/06/2007 11:26:00 PM
0
comments
 
 
Labels: PowerShell
You can play sounds in PowerShell in different ways and integrate them in your scripts to provide some kind of indication. One way is with write-host. You can pass the escape sequence `a  to write host. `a is the Alert corresponding special character: 
# play a screech sound (through the internal speaker, not useful on laptops) 
write-host "`a";
Another way is with a .NET class (.wav format).
# play the file once
$sound = new-Object System.Media.SoundPlayer;
$sound.SoundLocation="c:\WINDOWS\Media\notify.wav";
$sound.Play();
Note that the following process is asynchronously, meaning that the script wont hang until sound has finished playing. This example plays the file repeatedly until a condition met
$sound = new-Object System.Media.SoundPlayer;
$sound.SoundLocation="c:\WINDOWS\Media\notify.wav";
$sound.PlayLooping();
$flag=$false;
1..10 | foreach {
    if($_ -gt 5){$flag=$true} else{sleep -s 1}
    if($flag) { $sound.Stop() } 
}
write-host "Done";
There is another class called System.Media.SystemSounds. Pipe the class to get-member to reflect its static members:
PS C:\Scripts> [System.Media.SystemSounds] | gm -static
TypeName: System.Media.SystemSounds
Name            MemberType  Definition
----               ----------         ----------
(...)
Asterisk        Property         static System.Media.SystemSound Asterisk {get;}
Beep             Property         static System.Media.SystemSound Beep {get;}
Exclamation  Property         static System.Media.SystemSound Exclamation {get;}
Hand            Property         static System.Media.SystemSound Hand {get;}
Question       Property         static System.Media.SystemSound Question {get;}  
Each property emitted represents a system sound type. Now, Pipe each property to get-member
PS C:\Scripts> [System.Media.SystemSounds]::Asterisk | gm
TypeName: System.Media.SystemSound
Name         MemberType   Definition
----            ----------         ----------
(...)
Play           Method           System.Void Play()
ToString    Method           System.String ToString()  
Great, we can use the Play method,test each line in your console:
[System.Media.SystemSounds]::Asterisk.Play();
[System.Media.SystemSounds]::Beep.Play();
[System.Media.SystemSounds]::Exclamation.Play();
[System.Media.SystemSounds]::Hand.Play();
[System.Media.SystemSounds]::Question.Play();  
Finally, here is a one-liner for the job. It Utilizes the SoundPlayer(String) Constructor. It Initializes a new instance of the SoundPlayer class, and attaches the specified .wav file. 
 
(new-object Media.SoundPlayer "C:\WINDOWS\Media\notify.wav").play();
Posted by
Shay Levy
at
9/06/2007 02:36:00 PM
6
comments
 
 
Labels: one-liner, PowerShell, sound
Three articles on remoting published on The Code Project website.
As Jeffrey Snover stated on his last interview with SearchWinIT.com  ('remoting' will be built into the heart of the PowerShell engine).
At the meantime here are some others techniques in .NET.
A simple .NET Remoting example in three parts: the interface, the server, and the client. The client asks for your name, then sends it to the server. The server returns a personal greeting.
Remote Administration Tool (RAT) in C# - Part 3 (Reverse Connection Shell)
How to access server behind a gateway firewall using reverse connection shell technique
RemoteConsole
Remote console that allows to send commands to remote computer located in the Internet.
All articles includes source file in C#
Posted by
Shay Levy
at
9/06/2007 10:55:00 AM
3
comments
 
 
There is an excellent six part article walk through on Database Journal website by Muthusamy Anantha Kumar (aka The MAK) on PowerShell and SQL Server 2005 SMO. Everything you need to know in order to operate on SQL. The first parts introducing PowerShell concepts and some cmdlets to work with. From part III and on, there are fine examples on connecting to SQL server, collecting server information from different servers, create and backup databases and a lot more. A must read!
Check it out:
PowerShell and SQL Server 2005 SMO – Part I 
PowerShell and SQL Server 2005 SMO – Part II
PowerShell and SQL Server 2005 SMO – Part III
PowerShell and SQL Server 2005 SMO – Part IV
PowerShell and SQL Server 2005 SMO – Part V
PowerShell and SQL Server 2005 SMO – Part VI
Posted by
Shay Levy
at
9/05/2007 12:18:00 PM
2
comments
 
 
Labels: PowerShell, SMO, SQL
Thanks to Shahar Gvirtz for recording this 30 minutes webcast. Now the Israeli audience have a first glimpse (in Hebrew) to the power of the shell. I saw it and learned a few things. Cheers!.
Shahar explains the following topics:
You can download the webcast from here.
Posted by
Shay Levy
at
9/03/2007 10:08:00 PM
8
comments
 
 
Labels: hebrew, PowerShell
Sounds impossible, right... WRONNNG.
I saw this on a hebrew security/hacking blog by Guy Mizrahi: Zull, A Hacker's diary. This is the starting paragraph of the original news:
"The first time Scott Lunsford offered to hack into a nuclear power station, he was told it would be impossible. There was no way, the plant's owners claimed, that their critical components could be accessed from the Internet. Lunsford, a researcher for IBM's Internet Security Systems, found otherwise."
I wonder what other things we dont know about? One day we all will vanish in a click of a key|mouse|button and wont even notice. Read the rest on Forbes website.
Posted by
Shay Levy
at
9/02/2007 10:39:00 PM
0
comments
 
 
 A new PowerShell book Windows PowerShell: The Definitive Guide Guide , by Lee Holmes and Microsoft PowerShell team developer, will publish next month.
A new PowerShell book Windows PowerShell: The Definitive Guide Guide , by Lee Holmes and Microsoft PowerShell team developer, will publish next month.O'Reilly offers parts of the book for online reading (check the appendixes starting at Regular Expression Reference and downward).
Lets start cooking!
Posted by
Shay Levy
at
9/02/2007 08:48:00 PM
0
comments
 
 
Labels: books, PowerShell
By nature, Exchange 2007 is strongly integrated with Active Directory (AD) and as such, it exposes new types to interact with AD. A lot of the user object properties across all the AD forest are made available through the Get-User command-let. 
If you need to pass strings as "DistinguishedName" this function can help you validate them. 
function Validate-DistinguishedName{
    param([string]$dn)
    [Microsoft.Exchange.Data.Directory.ADObjectId]::IsValidDistinguishedName($dn)
}  
>> Validate-DistinguishedName "CN=Administrator,CN=Users,DC=homelab,DC=loc"
True
>> Validate-DistinguishedName "CN=Administrator,CN=Users,DC=homelab"
True
>> Validate-DistinguishedName "Shay@homelab.loc"
False
>> Validate-DistinguishedName "AB=CD,EF= G H"
True
Posted by
Shay Levy
at
9/01/2007 10:19:00 PM
0
comments
 
 
Labels: Exchange, PowerShell, validation
The other day I was looking for an option to colorize certain rows when using Format-* cmdlets. None of the cmdlets (including out-host, out-default) gives you the option to do that unless you define a custom PowerShell format/view file (ps1xml). I wish the Format-* cmdlets had a scriptblock parameter to which I can pass a piece of code that will colorize certain rows based on a criteria (maybe I'll fill a suggestion on Microsoft connect).
The major drawback of this custom format files is that you have to build them (requires some experience) for each type you want to print out, loading them into your environment via Update-FormatData and then executing them with the -view  parameter of the format-table or format-custom cmdlets. 
This method involves too much configuration and I was looking for a way to make the process more portable, depend less and operatable on any given command-let,  so I can easily use it on any PowerShell machine or script.
Lets say you want to colorize all text file names that begins with "s".
PS C:\Scripts> Get-ChildItem $env:WINDIR *.txt
Directory: Microsoft.PowerShell.Core\FileSystem::C:\WINDOWS
Mode       LastWriteTime               Length       Name
----          -------------                     ------         ----
-a---         7/28/2007 3:25 PM       8184          ModemLog_Agere Systems HDA Modem.txt
-a---         6/21/2007 11:43 AM     38280        ModemLog_HTC USB Modem.txt
-a---         3/5/2007   6:17 PM       3075         OEWABLog.txt
-a---         8/30/2007 10:51 AM     32622        SchedLgU.Txt
-a---         3/1/2007   1:56 AM       1012440    setuplog.txt
-a---         7/31/2006  7:41 PM       726072     SIGVERIF.TXT  
Get-ChildItem $env:WINDIR *.txt | foreach {
    if($_.name -match "^s.*"){
        write-host $_ -ForegroundColor "green";
    } else {
        write-host $_ -ForegroundColor "gray"
    }
}  
ModemLog_Agere Systems HDA Modem.txt
ModemLog_HTC USB Modem.txt
OEWABLog.txt
SchedLgU.Txt
setuplog.txt
SIGVERIF.TXT
As you can see, the foreach output contains only file names, no table headers nor additional property columns. It sure doesn't look like Format-Table's output. 
For about an hour or so I was struggling with PowerShell commands and made a lot of experiments. Finally, I was able to construct a filter. The filter accepts three parameters.
Color, property name to match against  and a regular expression pattern.
Surprisingly, the solution was pretty simple. Without the filter the code looks like:
Get-ChildItem $env:WINDIR *.txt | foreach {
    if($_.name -match "^s.*"){
        [console]::ForegroundColor="green"; $_;
    } else {
        [console]::ForegroundColor="white"; $_;
    }
} 
Well, here's the code for the filter:
filter colorize-row{
    param(
        [string]$color="green",
        [string]$prop="name",
        [string]$regex=$(throw "must supply regular expression pattern")  
    )
    
    # save current console colors
    #$bgc=[console]::BackgroundColor;
    $fgc=[console]::ForegroundColor; 
    if($_.$prop -match $regex){[console]::ForegroundColor=$color; $_}
    else{[console]::ForegroundColor=$fgc; $_}
    # revert to saved console colors
    #[console]::BackgroundColor=$bgc;
    [console]::ForegroundColor=$fgc; 
}
# get all text files in c:\windows that begins with "s", use default filter color
PS C:\Scripts> Get-ChildItem $env:WINDIR *.txt | colorize-row -regex "^s.*"
Directory: Microsoft.PowerShell.Core\FileSystem::C:\WINDOWS
Mode LastWriteTime Length Name
Now with get-process:
# get all processes which contains "svchost" in their names, colorize in yellow
PS C:\Scripts> get-process | colorize-row -regex "svchost" -prop "name" -color yellow 
Handles  NPM(K)    PM(K)    WS(K) VM(M)   CPU(s)   Id      ProcessName
-------      ------     -----       -----    -----      ------     --      -----------
...
...
     68       3           816       1264    14        0.02      524     sqlbrowser
    311       9          34172    20632  1100    1.02      436     sqlservr
     84       2           1064     1616     20       0.44      548     sqlwriter
   1894     246        34804   38528   217     197.80   180     svchost
    104       5          1772     2336     33       10.56    332     svchost
    126       4          2616     2160     36       3.80      580     svchost
    284      12         8124     5084     47       2.45      1152    svchost
     75       3          2332     1468     31       0.06       1512   svchost
    230       6         3464     2776     65       72.11     1640   svchost
    428      14        2368     2852     40       15.72     1692   svchost
     95      10        1796     1460      37       0.28       2696   svchost
    807       0        0          244         2        359.94    4        System
    207       7        6608     9788      62       114.42   5828    TextPad
...
...
 
About PowerShell Console Colors
You can specify one of the following enumeration values to the filter -color parameter. To get all possible enumeration color names/values:
>> [consolecolor]::GetNames([System.ConsoleColor])
-or- 
>> [consolecolor]::GetValues([System.ConsoleColor])  
-or- better use the following to generate a table of color names and there corresponding numeric values:
$colors=@([enum]::GetNames([consolecolor]));
0..($colors.length-1) | select @{n="Name";e={[string][enum]::parse([ConsoleColor],$_)}}, @{n="Constant";e={$_}} | format-table -autosize  
Name             Constant
----                   --------
Black                        0
DarkBlue                   1
DarkGreen                2
DarkCyan                  3
DarkRed                   4
DarkMagenta            5
DarkYellow                6
Gray                         7
DarkGray                  8
Blue                          9
Green                      10
Cyan                        11
Red                         12
Magenta                  13
Yellow                     14
White                     15
Posted by
Shay Levy
at
9/01/2007 06:32:00 PM
1 comments
 
 
Labels: filter, PowerShell