You can use the following command to display what functions that are part of your current shell.
Get-ChildItem function:*
To view the code contained in a function - in this example the function "mkdir":
$function:mkdir
If you would like to change a function, simply create a new function of the same name:
function C: {
Write-Host "You are not allowed on drive C: !"
Set-Location M:
}
The function TabExpansion is called to generate the list of possible completion matches when using the TAB key.
The function prompt determines what your command prompt looks like (se earlier post) .
Wednesday, December 27, 2006
Thursday, December 21, 2006
Configuring PowerShell
Enable scripts - in order to execute script in PowerShell, the default Executionpolicy of "Restricted", has to be changed to "Unrestricted":
Set-Executionpolicy Unrestricted
Instead of "Unrestricted" you could also selec RemoteSigned, AllSigned, Restricted, Default (to reset to the PowerShell default)
Configure my profile
Determine where my profile is stored through the following default variable:
$profile
Edit it by using
notepad $profile
To create the file first:
new-item -path $profile -itemtype file -force
# Set Aliases
set-alias n notepad
# Set Prompt
function prompt
{
$nbsp;$nbsp;$nbsp;$nbsp;Write-Host ("--< " + $(Get-Location) + " >--< " + $(Get-Date) + " >--") -foregroundcolor DarkRed
$nbsp;$nbsp;$nbsp;$nbsp;Write-Host "PS>" -nonewline -foregroundcolor Cyan
$nbsp;$nbsp;$nbsp;$nbsp;return " "
}
Set-Executionpolicy Unrestricted
Instead of "Unrestricted" you could also selec RemoteSigned, AllSigned, Restricted, Default (to reset to the PowerShell default)
Configure my profile
Determine where my profile is stored through the following default variable:
$profile
Edit it by using
notepad $profile
To create the file first:
new-item -path $profile -itemtype file -force
# Set Aliases
set-alias n notepad
# Set Prompt
function prompt
{
$nbsp;$nbsp;$nbsp;$nbsp;Write-Host ("--< " + $(Get-Location) + " >--< " + $(Get-Date) + " >--") -foregroundcolor DarkRed
$nbsp;$nbsp;$nbsp;$nbsp;Write-Host "PS>" -nonewline -foregroundcolor Cyan
$nbsp;$nbsp;$nbsp;$nbsp;return " "
}
- %UserProfile%\My Documents\WindowsPowerShell\profile.ps1 - This profile applies only to the to the current user, but affects all shells.
- %UserProfile%\\My Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1 - This profile applies only to the current user and the Microsoft.PowerShell shell.
- %windir%\system32\WindowsPowerShell\v1.0\profile.ps1 - This profile applies to all users and all shells.
- %windir%\system32\WindowsPowerShell\v1.0\ Microsoft.PowerShell_profile.ps1 - This profile applies to all users, but only to the Microsoft.PowerShell shell.
Wednesday, December 20, 2006
How much RAM have I got?
A small function to retrieve the number and size of RAM modules in a PC
function GetMem{
$a = Get-WmiObject win32_physicalmemory -computername $args[0]
Write-Host ("-" * 60)`n "Memory Configuration of" $args[0] `n("-" * 60)
foreach ($b in $a) {
Write-Host $b.tag `t $b.capacity "bytes" `t ($b.capacity/1mb) "mb"
}
}
Usage:
GetMem
function GetMem{
$a = Get-WmiObject win32_physicalmemory -computername $args[0]
Write-Host ("-" * 60)`n "Memory Configuration of" $args[0] `n("-" * 60)
foreach ($b in $a) {
Write-Host $b.tag `t $b.capacity "bytes" `t ($b.capacity/1mb) "mb"
}
}
Usage:
GetMem
Useful .NET stuff
One of the big advantages of PowerShell is the easy access to .NET
For instance, in order to gain access to the .NET functionality contained in datatime we
can use Get-Member to look at the available methods:
$a = [datetime]
Get-Member -InputObject $a -s
Or written in a shorter notation:
[datetime] | gm -s
We might find the IsLeapYear or Parse methods interisting, and decide to try them out:
[datetime]::Parse("2008/02/29 012:23:45")
What? January 29th? Maybe 2008 is a leapyear? Try this:
[datetime]::IsLeapYear(2008)
Another interesting part of .NET might be math . Lets use it to round the number 9876.54321 to one decimal:
[math]::round(9876.54321,1)
Other interesting uses for .NET:
[datetime]::now.addminutes(-1000000) #give me datetime 1 million minutes ago)
[console]::title = "My PoweShell window" #sets the title of the current console window
For instance, in order to gain access to the .NET functionality contained in datatime we
can use Get-Member to look at the available methods:
$a = [datetime]
Get-Member -InputObject $a -s
Or written in a shorter notation:
[datetime] | gm -s
We might find the IsLeapYear or Parse methods interisting, and decide to try them out:
[datetime]::Parse("2008/02/29 012:23:45")
What? January 29th? Maybe 2008 is a leapyear? Try this:
[datetime]::IsLeapYear(2008)
Another interesting part of .NET might be math . Lets use it to round the number 9876.54321 to one decimal:
[math]::round(9876.54321,1)
Other interesting uses for .NET:
[datetime]::now.addminutes(-1000000) #give me datetime 1 million minutes ago)
[console]::title = "My PoweShell window" #sets the title of the current console window
Tuesday, December 19, 2006
Memory consumption
Here are two small script used for displaying the name of currently running processes, as well as the amount of memory currently allocated (through VMM) to Virtual Machines (either Microsoft Virtual PC or Virtual Server):
function GetMem {
$processes = Get-WmiObject win32_process | Sort-Object -property WorkingSetSize -descending
$processes | format-table `
ProcessName, `
Handle, `
WorkingSetSize, `
@{label="in MB"; Expression={([Math]::round($_.WorkingSetSize / 1mb,1))}} `
-autosize
$TotalMem= 0
foreach ($process in $processes) {
$TotalMem = $TotalMem + $process.WorkingSetSize
}
$TotalMem_in_MB = [math]::round($TotalMem/1mb,1)
Write-Output "`tTotal mem used: `t $TotalMem ($TotalMem_in_MB MB)`n"
}
$a = GetMem; $a
function GetVMmem {
$virtualmachines = Get-WmiObject virtualmachine -namespace "root\vm\virtualserver"
$virtualmachines | format-table `
@{label="ProcessName"; Expression={("VirtualMachine " + $_.Name)}}, `
PhysicalMemoryAllocated, `
@{label="in MB"; Expression={([Math]::round($_.PhysicalMemoryAllocated/1mb,1))}} `
-autosize
$TotalMem = 0
foreach ($virtualmachine in $virtualmachines) {
$TotalMem = $TotalMem + $virtualmachine.PhysicalMemoryAllocated
}
$TotalMem_in_MB = [math]::round($TotalMem/1mb,1)
Write-Output "`tTotal mem used: `t $TotalMem ($TotalMem_in_MB MB)`n"
}
$b = GetVMmem; $b
function GetMem {
$processes = Get-WmiObject win32_process | Sort-Object -property WorkingSetSize -descending
$processes | format-table `
ProcessName, `
Handle, `
WorkingSetSize, `
@{label="in MB"; Expression={([Math]::round($_.WorkingSetSize / 1mb,1))}} `
-autosize
$TotalMem= 0
foreach ($process in $processes) {
$TotalMem = $TotalMem + $process.WorkingSetSize
}
$TotalMem_in_MB = [math]::round($TotalMem/1mb,1)
Write-Output "`tTotal mem used: `t $TotalMem ($TotalMem_in_MB MB)`n"
}
$a = GetMem; $a
function GetVMmem {
$virtualmachines = Get-WmiObject virtualmachine -namespace "root\vm\virtualserver"
$virtualmachines | format-table `
@{label="ProcessName"; Expression={("VirtualMachine " + $_.Name)}}, `
PhysicalMemoryAllocated, `
@{label="in MB"; Expression={([Math]::round($_.PhysicalMemoryAllocated/1mb,1))}} `
-autosize
$TotalMem = 0
foreach ($virtualmachine in $virtualmachines) {
$TotalMem = $TotalMem + $virtualmachine.PhysicalMemoryAllocated
}
$TotalMem_in_MB = [math]::round($TotalMem/1mb,1)
Write-Output "`tTotal mem used: `t $TotalMem ($TotalMem_in_MB MB)`n"
}
$b = GetVMmem; $b
Wednesday, December 13, 2006
Environment variables
To use the standard windows environment variables (temp, computername, windir, etc.) in PowerShell, you can use the following notation:
${env:temp}
Or, if the full names (not 8.3 DOS notation) are required:
[io.path]::GetFullPath($env:temp)
Note that if $env:path is needed, you have to use the first notation (which in this case returns the full path/file names).
${env:path}
[io.path]::GetFullPath($env:path) ## Won't work, as the returned value is too large.
${env:temp}
Or, if the full names (not 8.3 DOS notation) are required:
[io.path]::GetFullPath($env:temp)
Note that if $env:path is needed, you have to use the first notation (which in this case returns the full path/file names).
${env:path}
[io.path]::GetFullPath($env:path) ## Won't work, as the returned value is too large.
Sending emails from powershell
Here is a small script to send emails from PowerShell. Remember to use a valid SMTP server.
$SMTPserver = "mysmtp.nowhere.now"
$fileattachment = "c:\\boot.ini"
$from = "hans@nowhere.now"
$to = "somebody@somewhere.org"
$subject = "PowerShell Test"
$emailbody = "this is my very first email send through PowerShell 1.0"
$mailer = new-object Net.Mail.SMTPclient($SMTPserver)
$msg = new-object Net.Mail.MailMessage($from, $to, $subject, $emailbody)
$attachment = new-object Net.Mail.Attachment($fileattachment)
$msg.attachments.add($attachment)
$mailer.send($msg)
$SMTPserver = "mysmtp.nowhere.now"
$fileattachment = "c:\\boot.ini"
$from = "hans@nowhere.now"
$to = "somebody@somewhere.org"
$subject = "PowerShell Test"
$emailbody = "this is my very first email send through PowerShell 1.0"
$mailer = new-object Net.Mail.SMTPclient($SMTPserver)
$msg = new-object Net.Mail.MailMessage($from, $to, $subject, $emailbody)
$attachment = new-object Net.Mail.Attachment($fileattachment)
$msg.attachments.add($attachment)
$mailer.send($msg)
Tuesday, December 12, 2006
PowerShell can be strict
Normally PowerShell silently ignores the use of uninitialized variables.
For instance, the script below will simply assume that $b has no value, and return the value "5"
$a = 5
$a + $b
It is often useful to force PowerShell to return an error if an unitialized variable is used.
This can be accomplished by enabling "strict" mode:
Set-PSDebug -strict
If the earlier scritp is run again an error is returned:
$a = 5
$a + $b
The variable $b cannot be retrieved because it has not been set yet.
At line:1 char:7
+ $a + $b <<<<
For instance, the script below will simply assume that $b has no value, and return the value "5"
$a = 5
$a + $b
It is often useful to force PowerShell to return an error if an unitialized variable is used.
This can be accomplished by enabling "strict" mode:
Set-PSDebug -strict
If the earlier scritp is run again an error is returned:
$a = 5
$a + $b
The variable $b cannot be retrieved because it has not been set yet.
At line:1 char:7
+ $a + $b <<<<
Thursday, December 07, 2006
Jeffrey Snover of MSFT suggested the following (shorter) way of implementing yesterdays script:
[void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$myTitle = "Important Question"
$myText1 = "Is PowerShell useful to you ?"
$a = [Windows.Forms.MessageBox]::Show($myText1, $myTitle, "YesNoCancel", "Question")
$myText2 = "You answered: $a"
$a = [Windows.Forms.MessageBox]::Show($myText2, $myTitle, "Ok", "Information")
[void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$myTitle = "Important Question"
$myText1 = "Is PowerShell useful to you ?"
$a = [Windows.Forms.MessageBox]::Show($myText1, $myTitle, "YesNoCancel", "Question")
$myText2 = "You answered: $a"
$a = [Windows.Forms.MessageBox]::Show($myText2, $myTitle, "Ok", "Information")
Wednesday, December 06, 2006
Quick'n'dirty user interface
The example below shows a quick way to use a standard windows messagebox as a user interface, through Windows Forms.
[void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$myTitle = "Important Question"
$myText1 = "Is PowerShell useful to you ?"
$a = [Windows.Forms.MessageBox]::Show($myText1, $myTitle,`
[Windows.Forms.MessageBoxButtons]::YesNoCancel, `
[Windows.Forms.MessageBoxIcon]::Question)
$myText2 = "You answered: $a"
$b = [Windows.Forms.MessageBox]::Show($myText2, $myTitle, `
[Windows.Forms.MessageBoxButtons]::Ok, `
[Windows.Forms.MessageBoxIcon]::Information)
[void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$myTitle = "Important Question"
$myText1 = "Is PowerShell useful to you ?"
$a = [Windows.Forms.MessageBox]::Show($myText1, $myTitle,`
[Windows.Forms.MessageBoxButtons]::YesNoCancel, `
[Windows.Forms.MessageBoxIcon]::Question)
$myText2 = "You answered: $a"
$b = [Windows.Forms.MessageBox]::Show($myText2, $myTitle, `
[Windows.Forms.MessageBoxButtons]::Ok, `
[Windows.Forms.MessageBoxIcon]::Information)
Tuesday, December 05, 2006
PowerShell, SQL & SMO
On november 30th I showed how to access a SQL Server using ADO. Todays script does excatly the same, but uses SMO instead of ADO:
function ShowAllDB_SMO {
[void][reflection.assembly]::LoadWithPartialName( "Microsoft.SqlServer.ConnectionInfo" );
[void][reflection.assembly]::LoadWithPartialName( "Microsoft.SqlServer.SmoEnum" );
[void][reflection.assembly]::LoadWithPartialName( "Microsoft.SqlServer.Smo" );
$server = new-object( 'Microsoft.SqlServer.Management.Smo.Server' ) $args[0]
foreach ($database in $server.databases) {
$temp0 = $database.ID
$temp1 = $database.Name
Write-Output "$temp0 ; $temp1"
}
}
To use the function:
ShowAllDBs_SMO [server or server\instance]
function ShowAllDB_SMO {
[void][reflection.assembly]::LoadWithPartialName( "Microsoft.SqlServer.ConnectionInfo" );
[void][reflection.assembly]::LoadWithPartialName( "Microsoft.SqlServer.SmoEnum" );
[void][reflection.assembly]::LoadWithPartialName( "Microsoft.SqlServer.Smo" );
$server = new-object( 'Microsoft.SqlServer.Management.Smo.Server' ) $args[0]
foreach ($database in $server.databases) {
$temp0 = $database.ID
$temp1 = $database.Name
Write-Output "$temp0 ; $temp1"
}
}
To use the function:
ShowAllDBs_SMO [server or server\instance]
Monday, December 04, 2006
Oneliner
Todays script is a oneliner that sums up the memory consumption of alle running processes (or rather all visible running processes). It also demonstrates the use of ";" as a line separator
$a = get-process; foreach ($i in $a) {$sum = $sum + $i.workingset}; $sum / 1mb
$a = get-process; foreach ($i in $a) {$sum = $sum + $i.workingset}; $sum / 1mb
Thursday, November 30, 2006
PowerShell, SQL & ADO
The following function connects to a SQL server through ADO, and queries the master database for a list of the database id (dbid) and name of all databases on the server:
function ShowAllDBs {
$objConnection = New-Object -comobject ADODB.Connection
$objRecordset = New-Object -comobject ADODB.Recordset
$query = "SELECT dbid, name FROM master.dbo.sysdatabases ORDER BY dbid"
$objConnection.Open("Provider=SQLOLEDB; Data Source=" + $args[0] + "; Initial Catalog=master; Integrated Security=SSPI")
$objRecordset.Open($query, $objConnection, $adOpenStatic, $adLockOptimistic)
$objRecordset.MoveFirst()
do {
$temp0 = $objRecordset.Fields.Item("dbid").Value
$temp1 = $objRecordset.Fields.Item("name").Value
Write-Output "$temp0 : $temp1"
$objRecordset.MoveNext()
} until ($objRecordset.EOF -eq $True)
$objRecordset.Close()
$objConnection.Close()
}
To use the function:
ShowAllDBs [server or server\instance]
function ShowAllDBs {
$adOpenStatic = 3
$adLockOptimistic = 3$objConnection = New-Object -comobject ADODB.Connection
$objRecordset = New-Object -comobject ADODB.Recordset
$query = "SELECT dbid, name FROM master.dbo.sysdatabases ORDER BY dbid"
$objConnection.Open("Provider=SQLOLEDB; Data Source=" + $args[0] + "; Initial Catalog=master; Integrated Security=SSPI")
$objRecordset.Open($query, $objConnection, $adOpenStatic, $adLockOptimistic)
$objRecordset.MoveFirst()
do {
$temp0 = $objRecordset.Fields.Item("dbid").Value
$temp1 = $objRecordset.Fields.Item("name").Value
Write-Output "$temp0 : $temp1"
$objRecordset.MoveNext()
} until ($objRecordset.EOF -eq $True)
$objRecordset.Close()
$objConnection.Close()
}
To use the function:
ShowAllDBs [server or server\instance]
Wednesday, November 29, 2006
Functions in PowerShell
Here is how to create a simple function in PowerShell. The function takes a single argument, and returns the twice the given amount. Note that the function works on both integers and strings (PowerShell handles multiplication of strings by repeating the string the given number of times).:
function MultiplyByTwo {
$temp = $args[0] * 2
Write-Output $temp
}
MultiplyByTwo 42
MultiplyByTwo "Bluebeard"
This is another example. The RetrieveData function calls two independent functions in order to retrieve the number of CPUs and the amount of memory of a given host:
function GetMem {
$temp = Get-WmiObject "Win32_LogicalMemoryConfiguration" -computername $args[0]
$MemInBytes = $temp.TotalPhysicalMemory * 1kb
Write-Output $MemInBytes
}
function GetNumCPU {
$temp = Get-WmiObject "Win32_ComputerSystem" -computername $args[0]
$nocpu = $temp.NumberOfProcessors
Write-Output $nocpu
}
function RetrieveData {
$tmpNoCPU = GetNumCPU $args[0]
$tmpMemInBytes = GetMem $args[0]
$computername = $args[0]
Write-Output "The Computer $computername has $tmpNoCPU CPU(s) and $tmpMemInBytes bytes of RAM installed."
}
RetrieveData "localhost"
function MultiplyByTwo {
$temp = $args[0] * 2
Write-Output $temp
}
MultiplyByTwo 42
MultiplyByTwo "Bluebeard"
This is another example. The RetrieveData function calls two independent functions in order to retrieve the number of CPUs and the amount of memory of a given host:
function GetMem {
$temp = Get-WmiObject "Win32_LogicalMemoryConfiguration" -computername $args[0]
$MemInBytes = $temp.TotalPhysicalMemory * 1kb
Write-Output $MemInBytes
}
function GetNumCPU {
$temp = Get-WmiObject "Win32_ComputerSystem" -computername $args[0]
$nocpu = $temp.NumberOfProcessors
Write-Output $nocpu
}
function RetrieveData {
$tmpNoCPU = GetNumCPU $args[0]
$tmpMemInBytes = GetMem $args[0]
$computername = $args[0]
Write-Output "The Computer $computername has $tmpNoCPU CPU(s) and $tmpMemInBytes bytes of RAM installed."
}
RetrieveData "localhost"
Variables and types
A variable in PowerShell must begin with the dollarsign ($). The name of the variable stops at the first word breaking character (such as space, comma or period). If special characters are needed in a variable, name curly braces can be used to surround the variable name:
$myvar = "normal variable name"
$myvar
${ugh!b££!!¤&(} = "special variable name"
${ugh!b££!!¤&(}
In order to determine the type of a variable, the GetType method can be used:
$a = 1234
$a.GetType() ## Displays the type of $a
$b = "1234"
$b.GetType()
[int]$c = $b ## casts $c as an integer (int32)
$c.GetType()
To get information of properties and methods of a given object - in this case a variable - use Get-Member -InputObject.
Notice the difference between the string variable $b and the integer cariable $c
Get-Member -InputObject $b
Get-Member -InputObject $c
Examples - using various methods on a variable:
$d = "Hello world! I'm back again!"
$d.Split()
$d.ToLower()
$d.ToUpper()
$myvar = "normal variable name"
$myvar
${ugh!b££!!¤&(} = "special variable name"
${ugh!b££!!¤&(}
In order to determine the type of a variable, the GetType method can be used:
$a = 1234
$a.GetType() ## Displays the type of $a
$b = "1234"
$b.GetType()
[int]$c = $b ## casts $c as an integer (int32)
$c.GetType()
To get information of properties and methods of a given object - in this case a variable - use Get-Member -InputObject.
Notice the difference between the string variable $b and the integer cariable $c
Get-Member -InputObject $b
Get-Member -InputObject $c
Examples - using various methods on a variable:
$d = "Hello world! I'm back again!"
$d.Split()
$d.ToLower()
$d.ToUpper()
Tuesday, November 28, 2006
SQLDMO
Here is a small script using SQLDMO against a MS SQL Server 2000 or 2005 to obtain the TCP port number currently used. I know the Books Online for SS05 indicates that DMO is no longer supported - well I guess that they're wrong:
$s = New-Object -comobject "SQLDMO.SQLServer"
$s.loginsecure = $true
$s.connect("SERVERNAME01")
$s.registry.tcpport
$s.close()
$s = New-Object -comobject "SQLDMO.SQLServer"
$s.loginsecure = $true
$s.connect("SERVERNAME01")
$s.registry.tcpport
$s.close()
Two ways of writing foreach
There are two ways of creating foreach statements in PowerShell
$b = 'hans','soren','ib','poul','hanne','william','ann-marie'$b | Foreach-Object {Write-Host $_}
Or
$b = 'hans','soren','ib','poul','hanne','william','ann-marie'
Foreach ($a in $b) {Write-Host $a}
Basic Stuff
Literal Strings
'text' indicate a literal string in PowerShell, while "text" is used when variables and escape chars are needed.
$c = "Julemanden"
Write-Host 'Santa Claus is called $c in Denmark'
Write-Host "Santa Claus is called $c in Denmark"
Multidimensional Arrays
$a = @( (1,2,3,4,5) , (6,7,8,9,0) )
$a[0][0]
$a[1][1]
'text' indicate a literal string in PowerShell, while "text" is used when variables and escape chars are needed.
$c = "Julemanden"
Write-Host 'Santa Claus is called $c in Denmark'
Write-Host "Santa Claus is called $c in Denmark"
Multidimensional Arrays
$a = @( (1,2,3,4,5) , (6,7,8,9,0) )
$a[0][0]
$a[1][1]
Subscribe to:
Posts (Atom)