Welcome to MSDN Blogs Sign in | Join | Help

Renaming a network connection with netsh

Example:

netsh interface set interface name="Local Area Connection" newname="ExampleLan"

Posted by mwilbur | 1 Comments

Powershell Template Engine

A template engine that allows you to have powershell expressions in your templates is a very powerful thing: http://weblogs.asp.net/soever/archive/2006/12/31/a-templating-engine-using-powershell-expressions.aspx

Example Input:

Multi Line Expression:
[[ get-date
1..20
]]

Define function [[ function get-theanswer {42;} ]]

Single Line: [[ theanswer ]]

EOF

Example Output:

Multi Line Expression:
03/14/2007 22:38:09 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

Define function

Single Line: 42

EOF

The implementation uses dynamic code generation to build an assembly in order to have a delegate to pass to regex.replace. 

Using code generation felt a bit over complicated, and I wondered if it could be simpler.

Some thinking and tinkering later, I arrived at a working implementation.

Getting the multiline regex expression working correctly caused me some difficulty; as it only seems to correctly handle \R as a line separator.

I also added the ability to pipe text to the script, since I like to use the syntax: gc file.txt | expand-template

Now as with any powerful tool you'll need to be careful, and be sure that you fully trust the template file (other wise you'll be vulnerable to a code injection attack)

Expand-Template.ps1:

param ($text="",$BeginTag='[[',$EndTag=']]') 
$begintag = [regex]::escape($begintag) 
$endtag = [regex]::escape($endtag) 
$output="" 

$input | %{$text+=[string]$_ + "`r"} 

while ($text -match "(?m)(?<pre>.*?)$begintag(?<exp>.*?)$endtag(?<post>.*)") { 
  $text = $matches.post 
  $output += $matches.pre 
  $output += invoke-expression $matches.exp 
} 

$output += $text 
$output -replace "`r", [environment]::newline 
Posted by mwilbur | 0 Comments

get-SHA256

Get the SHA256 hash in one line of powershell:

function get-sha256 {
param($file);[system.bitconverter]::tostring([System.Security.Cryptography.sha256]::create().computehash([system.io.file]::openread((resolve-path $file)))) -replace "-",""
}

Posted by mwilbur | 1 Comments

get-datatable.ps1

get-datatable.ps1 is an improvement on the get-dataset.ps1 from an earlier post. Instead of returning a dataset it returns a DataTable; and a UpdateSql method is added to the object returned, so you don't need a separate script to send the changes back to sql.

This allows updates to a small table to look like:

$t = datatable "select * from stuff" -db foo
$t | %{ .... update the data rows ... }
$t.UpdateSql()

Get-DataTable.ps1:

param ($sql,$server=".",$db) 

$connectionstring= "Server=$server;database=$db;trusted_connection=yes;" 
$dt = new-object data.DataTable 
$da = New-Object system.data.sqlclient.sqldataadapter $sql, $connectionstring 
$null = $da.Fill($dt) 
$dt.ExtendedProperties["sql"]= $sql 
$dt.ExtendedProperties["connectionstring"]= $connectionstring 

$dt = add-member ScriptMethod UpdateSql { 
$da = New-Object system.data.sqlclient.sqldataadapter $this.ExtendedProperties["sql"], $this.ExtendedProperties["connectionstring"] 

$cb = new-object system.data.sqlclient.sqlcommandbuilder $da 
$da.UpdateCommand = $cb.GetUpdateCommand() 
$da.InsertCommand = $cb.GetInsertCommand() 
$da.DeleteCommand = $cb.GetDeleteCommand() 
$null = $da.Update($this) 
} -in $dt -pass 

#return data table in array so table doesn't get decomposed into an array of data rows. 
,$dt
Posted by mwilbur | 0 Comments

Managing Performance Counters via Command Line

When it comes to scripting the setup of performance counters Logman is your friend; and Relog comes in really handy for converting a binary log to SQL log.

Posted by mwilbur | 0 Comments

Windows Automated Installation Kit (AIK)

It's great to see powerful tools be made publicly available; winpe and imagex are powerful tools I've been using for some time to deploy systems and recover from hardware & software failures.

Windows Automated Installation Kit (AIK)

Overview

The Windows Automated Installation Kit (Windows AIK) is designed to help corporate IT professionals customize and deploy the Microsoft Windows Vista™ family of operation systems. By using Windows AIK, you can perform unattended Windows installations, capture Windows images with ImageX, and create Windows PE images.

Posted by mwilbur | 1 Comments

Updating a DataSet with Powershell and saving changes back to SQL

This example uses the AdventureWorks sample database.

# get the dataset 
PS C:\demo> $ds = .\get-dataset.ps1 "select * from Production.ProductModel" -db adventureworks 
# write out xml from the instructions column into seperate files 
PS C:\demo> $ds.Tables[0] | ?{$_["instructions"] -ne [dbnull]::value } | %{$_["instructions"]| sc "productmodel-$($_['productmodelid']).xml"} 
# verify output 
PS C:\demo> ls productmodel-* 

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

Mode                LastWriteTime     Length Name   
----                -------------     ------ ----                                                                  
-a---         2/25/2007   8:47 PM       5567 productmodel-10.xml
-a---         2/25/2007   8:47 PM       2142 productmodel-43.xml
-a---         2/25/2007   8:47 PM       1967 productmodel-44.xml
-a---         2/25/2007   8:47 PM       4051 productmodel-47.xml
-a---         2/25/2007   8:47 PM       4078 productmodel-48.xml
-a---         2/25/2007   8:47 PM       1927 productmodel-53.xml
-a---         2/25/2007   8:47 PM       1565 productmodel-66.xml
-a---         2/25/2007   8:47 PM       1572 productmodel-67.xml
-a---         2/25/2007   8:47 PM       5340 productmodel-7.xml

# now lets make some xml files for product model 1-5 
PS C:\demo> 1..5 | %{cp productmodel-10.xml productmodel-$_.xml} 
# Update the dataset with the new xml content from the files 
PS C:\demo> $ds.Tables[0] | %{$file = "productmodel-$($_['productmodelid']).xml";if (test-path $file) {$_["instructions"] = [string]::join("`r`n",(gc $file))}} 
# save changes back to SQL 
PS C:\demo> .\save-datasetchanges.ps1 $ds 

Get-DataSet.ps1 stores the sql command and connection string used to create the dataset as extended properties on the dataset. This is used by Save-DataSetChanges.ps1 to construct a SqlCommandBuilder object; which is then used to create the update/insert/delete command objects and update the SQL Server using a SqlDataAdapter.

get-dataset.ps1:

param ($sql,$server=".",$db) 

$connectionstring= "Server=$server;database=$db;trusted_connection=yes;" 
$ds = new-object data.dataset 
$da = New-Object system.data.sqlclient.sqldataadapter $sql, $connectionstring 
$null = $da.Fill($ds) 
$ds.ExtendedProperties["sql"]= $sql 
$ds.ExtendedProperties["connectionstring"]= $connectionstring 
$ds

save-datasetchanges.ps1:

param ([system.data.dataset]$dataset)  

$ds = $dataset 
$da = New-Object system.data.sqlclient.sqldataadapter $ds.ExtendedProperties["sql"], $ds.ExtendedProperties["connectionstring"] 

$cb = new-object system.data.sqlclient.sqlcommandbuilder $da 
$da.UpdateCommand = $cb.GetUpdateCommand() 
$da.InsertCommand = $cb.GetInsertCommand() 
$da.DeleteCommand = $cb.GetDeleteCommand() 
$null = $da.Update($ds) 
Posted by mwilbur | 1 Comments

Capturing SQL Generated by SMO in Powershell

The following example uses the get-sqlserver.ps1 script in my search path.

get-sqlserver.ps1:

param ($server=".")  
$null = [reflection.assembly]::loadwithpartialname("microsoft.sqlserver.smo") 
new-object Microsoft.SqlServer.Management.Smo.Server $server;

This example will shows how to use SMO objects to generate a SQL Script that will drop all the rowguid columns from the adventure works database:

PS C:\demo> $srv = get-sqlserver  
PS C:\demo> $db = $srv.Databases["adventureworks"] 
# Find the tables that have a rowguid column 
PS C:\demo> foreach ($tbl in $db.tables) {$tbl.columns | %{ if($_.name -eq "rowguid") {$tbl.name}}} 
Employee 
EmployeeAddress 
Address 
AddressType 
Contact 
StateProvince 
Product 
... 

# set SMO connection to capture mode 
PS C:\demo> $srv.ConnectionContext.SqlExecutionModes = [Microsoft.SqlServer.Management.Common.SqlExecutionModes]::capturesql 

# drop the row guid column & alter the table  
#  SMO is set to capture only so the database is not updated 
PS C:\demo> foreach ($tbl in $db.tables) {$tbl.columns | %{ if($_.name -eq "rowguid") {$_.drop();$tbl.alter();}}} 

# Check the captured sql
PS C:\demo> $srv.ConnectionContext.CapturedSql.Text USE [adventureworks] ALTER TABLE [HumanResources].[Employee] DROP CONSTRAINT [DF_Employee_rowguid] ALTER TABLE [HumanResources].[Employee] DROP COLUMN [rowguid] ... # save the sql to a file PS C:\demo> $srv.ConnectionContext.CapturedSql.Text | sc update.sql
Posted by mwilbur | 0 Comments

EventTriggers

This could be usefull; I always like knowing about obscure commands that are on every box I work with.

eventtriggers[.exe] /create [/s Computer [/u Domain\User [/p Password]]] /tr TriggerName [/l [APPLICATION] [SYSTEM] [SECURITY] ["DNS Server"] [LOG] [DirectoryLogName] [*]] {[/eid ID] | [/t {ERROR | INFORMATION | WARNING | SUCCESSAUDIT | FAILUREAUDIT}] | [/so Source]} [/d Description] /tk TaskName

eventtriggers create:
This command creates a new event trigger that monitors and acts upon the occurrence of log events of given criteria.

http://technet2.microsoft.com/WindowsServer/en/library/e33bcf4c-dece-4b47-9bb7-31ecfcbc76d51033.mspx?mfr=true

Posted by mwilbur | 0 Comments

Remote Desktop shortcut keys

Remote Desktop has some really handy shortcuts that are documented right there in the help file:
Shortcut key Description
ALT+PAGE UP Switches between programs from left to right.
ALT+PAGE DOWN Switches between programs from right to left.
ALT+INSERT Cycles through the programs in the order they were started.
ALT+HOME Displays the Start menu.
CTRL+ALT+BREAK Switches the client between a window and full screen.
CTRL+ALT+END Brings up the Windows Security dialog box.
ALT+DELETE Displays the Windows menu.
CTRL+ALT+Minus (-) symbol on the numeric keypad Places a snapshot of the active window, within the client, on the Terminal server clipboard (provides the same functionality as pressing PrintScrn on a local computer.)
CTRL+ALT+Plus (+) symbol on the numeric keypad Places a snapshot of the entire client window area on the Terminal server clipboard (provides the same functionality as pressing ALT+PrintScrn on a local computer.)
Posted by mwilbur | 0 Comments

Powershell script that can schedule itself to run later

From time to time I find it useful to schedule tasks to run on my machine. I often realize that many people are unaware that windows 2003 has a built in task scheduler; and even more of a rarity for them to be aware it can be managed via the command line. 

Enter SCHTASKS http://support.microsoft.com/kb/814596/

In the past I would crate a batch file to create the schedules; just to make it easy and repeatable. Having the setup separate from the batch file that does the work always bugged me.

The other day I when I found the need to have a task run every five minutes, I did it in powershell.  I thought to myself hey this is powershell, we’ve got some more power here; what if this script could schedule it’s self? And that’s how this idea was born.

When run without parameters it executes normaly.
Specify the -schedule switch to have it schedule itself.
For details on schtasks options see: http://support.microsoft.com/kb/814596/

Selfscheduling.ps1:

param ([switch] $schedule)

if ($schedule) {
$taskname = $myinvocation.mycommand.definition -replace '\W','_'
schtasks /create  /sc MINUTE /MO 5 /tn "$taskname" /tr "powershell -c $($myinvocation.mycommand.definition)"
return;
}

#switch to directory where the script lives
pushd (split-path -parent $myinvocation.mycommand.definition)

#insert useful code here
write-host "Hello World"

popd

Posted by mwilbur | 1 Comments
Filed under:

Powershell 1 liner: Key Value pairs from text file to hashtable

Example Problem:
You have a text file that contains key value pair and you want to use them as a hash table in powershell.

Values.txt:
key1=value1
key2=value2
key3=value42

One way to do it:
PS C:\temp> gc values.txt | %{$h = @{}} {if ($_ -match "(.*)=(.*)") {$h[$matches[1]]=$matches[2];}}

PS C:\temp> $h

Name                           Value
----                           -----
key3                           value42
key2                           value2
key1                           value1
Posted by mwilbur | 0 Comments
Filed under:
 
Page view tracker