Using PowerShell $Error variable

The $Error variable hold a collection of information, and that’s why using $Error[0] can get to your error message objects.  Also the $Error[0] variable will hold the last error message encountered until the PowerShell session ends.

Sample Console session:
Windows PowerShell
Copyright (C) 2009 Microsoft Corporation. All rights reserved.

PS C:\Users\maxt> $error 
PS C:\Users\maxt>
PS C:\Users\maxt> Ip[config
Ip[config : The term ‘Ip[config’ is not recognized as the name of a cmdlet, function, script file, or operable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:10
+ Ip[config <<<<
    + CategoryInfo          : ObjectNotFound: (Ip[config:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

PS C:\Users\maxt>
PS C:\Users\maxt> $error[0]
Ip[config : The term ‘Ip[config’ is not recognized as the name of a cmdlet, function, script file, or operable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.

At line:1 char:10
+ Ip[config <<<<
    + CategoryInfo          : ObjectNotFound: (Ip[config:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

PS C:\Users\maxt>
PS C:\Users\maxt> $Error[0].InvocationInfo.line
Ip[config
PS C:\Users\maxt> 

Starting a new PowerShell session the $Error will be empty.  Type a bad command “Ip[onfig” and the $Error variable will get populated.  Then we use the $Error[0] to display and access the rest of the information it holds.

Don’t forget to use the Get-Member to expose your PS variable objects.

PS C:\Users\maxt> $Error | Get-Member

   TypeName: System.Management.Automation.ErrorRecord

Name                  MemberType     Definition
—-                  ———-     ———-
Equals                Method         bool Equals(System.Object obj)
GetHashCode           Method         int GetHashCode()
GetObjectData         Method         System.Void GetObjectData(System.Runtime.Serialization.Serializatio
GetType               Method         type GetType()
ToString              Method         string ToString()
CategoryInfo          Property       System.Management.Automation.ErrorCategoryInfo CategoryInfo {get;}
ErrorDetails          Property       System.Management.Automation.ErrorDetails ErrorDetails {get;set;}
Exception             Property       System.Exception Exception {get;}
FullyQualifiedErrorId Property       System.String FullyQualifiedErrorId {get;}
InvocationInfo        Property       System.Management.Automation.InvocationInfo InvocationInfo {get;}
PipelineIterationInfo Property       System.Collections.ObjectModel.ReadOnlyCollection`1[[System.Int32,
TargetObject          Property       System.Object TargetObject {get;}
PSMessageDetails      ScriptProperty System.Object PSMessageDetails {get=& { Set-StrictMode -Version 1;

PS C:\Users\maxt> $Error.InvocationInfo
PS C:\Users\maxt> $Error[0].InvocationInfo

MyCommand        :
BoundParameters  : {}
UnboundArguments : {}
ScriptLineNumber : 1
OffsetInLine     : 9
HistoryId        : -1
ScriptName       :
Line             : ip[onfig
PositionMessage  :
                   At line:1 char:9
                   + ip[onfig <<<<
InvocationName   : ip[onfig
PipelineLength   : 0
PipelinePosition : 0
ExpectingInput   : False
CommandOrigin    : Internal

Finally, we can get deeper in the $Error[0] object to extract the line that failed during execution.  If you need to display the failed command line you can use the following line:

$Error[0].InvocationInfo.line

PS C:\Users\maxt> $Error[0].InvocationInfo.line
ip[onfig
PS C:\Users\maxt>

It’s all about understanding your .NET objects.  Hope this help!
🙂

Installing SQL Server 2012 on Server Core 2012

The Truth, it wasn’t easy.  I look around some blogs but they always failed to mention what was done prior to the actual installation of SQL Server on a Server Core machine.  But, installing SQL Server on a Server Core 2012 makes it better if you have installed the Minimal-Server interface.  Yes! The new Server Core gives you the flexibility to partially add and remove the GUI shell.

Here’s what I did to get my SQL Server on a Server Core 2012 installed in a Virtual Machine.   Remember, when using Hyper-V, you can use the shapshot feature to create a point of recovery state in case you need to go back and start over.

Setting up Server Core 2012 with Minimal-Server Interface

First, I need to make sure Server Core has all the components in place.  In my test building a virtual machine I found that I needed to have:

1. Connection to the internet or some features will fail to install.

2. I need to assign a static IP Address (so I can join my domain).

3. Add an admin user account to the local administrator group (Workgroup or Domain admin user account).

4. Configure Remote Management.

5. Configure Remote Desktop.

To get this done I use the vbscript application “SConfig” tool to assist configuring my Server Core.  It’s a great tool, and it can be executed from PowerShell prompt too.

Configuring Server Core 2012 with VBScript "SConfig" Tool

Now, keep in mind you need to meet some requirements before installing SQL Server.  Most important is installing .NET Framework 3.5.  But, if you successfully install the following Windows Features to enable the Minimal-Server interface on Server Core 2012 then you should be fine for setting up SQL Server.  Again, connection to the internet is mandatory (at least in my scenario).

Here’s the features required to *install and enabled the Minimal-Server interface:

Install-WindowsFeature -Name UpdateServices

Install-WindowsFeature -Name Net-Framework-Core

Install-WindowsFeature -Name Server-Gui-Mgmt-Infra -restart

*Note: Notice these are PowerShell commands.

Yes! You can use PowerShell.  Just type *PowerShell as soon as the command prompt shows up and you can continue building the you Server Core.  A restart of the server will be needed.

Tip: To start PowerShell in Server Core 2012 DOS command prompt, type “PowerShell” and press Enter .  Then, to get back to DOS command prompt, type the “Exit” and press Enter.

To get a list of all installed features, use the following PowerShell command:

Get-WindowsFeature

Use the above command verify the .NET Framework 3.5 features has been enabled.  Of course, after rebooting the server you will notice the Server Manager GUI will be displayed along with the command prompt.  This is a good indication .NET Framework is in place.

After rebooting, you will get the Minimal-Server Interface.

Server Core 2012 with Minimal-Server interface

Installing SQL Server 2012 on Server Core 2012

Now, I’m are ready to install SQL Server 2012.  I have attached the SQL Server 2012 ISO image to my virtual machine.  Here’s the *Setup command to install: SQLEngine, AS, IS, and Conn.  For more information: http://msdn.microsoft.com/en-us/library/hh231669.aspx

Setup.exe /qs /ACTION=Install /FEATURES=SQLEngine,AS,IS,Conn /INSTANCENAME=”MSSQLSERVER” /SQLSVCACCOUNT=”DomainName” \AccountName” /SQLSVCPASSWORD=”*******”  /SQLSYSADMINACCOUNTS=”DomainName\AccountName” /AGTSVCACCOUNT=”NT AUTHORITY \Network Service” /ASSVCACCOUNT=”NT Service\MSSQLServerOLAPService” /ASSYSADMINACCOUNTS=””DomainName\AccountName” /ASSERVERMODE=”TABULAR” /TCPENABLED=1 /IACCEPTSQLSERVERLICENSETERMS

*Note: The above command is a *one-liner.

A Word of Caution. I’ve experience that sometimes the setup will finished with no indication that everything completed successfully.  To find later that the SQLEngine wasn’t installed

I had to verify the SQL Server instance was installed by looking at the Microsoft SQL Server folder under “C:\Program Files\Microsoft SQL Server” and use the PowerShell command “Get-Service” to see all services were active.

Another way to make sure SQL Server was installed on Server Core

Now, I need to configure the SQL Remote Access to option “1” using the “SQLCMD -A” command from the “C:\Program Files\Microsoft SQL Server\110\tools\binn” folder with the following T-SQL lines:

EXEC sys.sp_configure N’remote access’, N’1′

GO

RECONFIGURE WITH OVERRIDE

GO

Exit

Using SQLCMD -A command

Test SQL Server connection remotely

Now, before trying to connect from another machine, I need to configure the Windows *Firewall rule to allow access to my SQL Server by executing the following line in the DOS command prompt:

netsh firewall set portopening protocol = TCP port = 1433 name = SQLPort mode = ENABLE scope = SUBNET profile = CURRENT

Setting Firewall SQL Server rule

*Note: This command will  execute but read the warning message

The moment of Truth!  Testing that I can connect to SQL Server on Server Core 2012 from a Windows 8 Desktop using SSMS.

Windows 8 client Virtual Machine connecting to SQL on Server Core 2012

Conclusion

In this blog I have accomplished the following in a virtual machine:

1. Build a Server Core 2012 with Minimal-Shell interface.

2. Use the VBScript “SConfig” to help configuring my server.

3. Install SQL Server 2012: Engine, Analysis Services, and Integration Services.

4. Verify remote connectivity using SSMS from a desktop machine.

I’m just having fun with technology!

Windows PowerShell v3.0 (RTM) Resource Links- Start Now!

As the RTM release of PowerShell will becomes available soon, here’s some resource information links you may want to take into consideration.

Download the Windows Management Framework 3.0 RTM: http://www.microsoft.com/en-us/download/details.aspx?id=34595

Windows PowerShell 3.0 and Server Manager Quick Reference Guides: http://www.microsoft.com/en-us/download/details.aspx?id=30002

Management and Tools for Windows Server 2012: http://technet.microsoft.com/en-us/library/hh801900

New V3 Language Features: http://blogs.msdn.com/b/powershell/archive/2012/06/14/new-v3-language-features.aspx

Intellisense in Windows PowerShell ISE 3.0: http://blogs.msdn.com/b/powershell/archive/2012/06/13/intellisense-in-windows-powershell-ise-3-0.aspx

Basic installation guide for Windows PowerShell Web Access: http://blogs.msdn.com/b/powershell/archive/2012/06/27/windows-powershell-web-access-basic-installation-guide.aspx

High Level Architecture of Windows PowerShell Workflow (Part 1): http://blogs.msdn.com/b/powershell/archive/2012/06/15/high-level-architecture-of-windows-powershell-workflow-part-1.aspx

High Level Architecture of Windows PowerShell Workflow (Part 2): http://blogs.msdn.com/b/powershell/archive/2012/06/19/high-level-architecture-of-windows-powershell-workflow-part-2.aspx

Managing Storage with Windows PowerShell on Windows Server 2012: http://blogs.msdn.com/b/san/archive/2012/07/03/managing-storage-with-windows-powershell-on-windows-server-2012.aspx

Getting Started with Windows Azure PowerShell: http://msdn.microsoft.com/en-us/library/windowsazure/jj156055.aspx

And, most important of all, check the TechEd North America 2012PowerShell” videos: http://channel9.msdn.com/Events/TechEd/NorthAmerica/2012?sort=sequential&direction=desc&term=PowerShell

This should get you started.  So, what’s preventing you to learn PowerShell?  Start now.

Telnet Automation with PowerShell made simple…

Whaoo! After hours searching the internet for some code that could simply help me automate my Telnet sessions, and not finding a simple solution was frustrating. I had to give up and admit that this one goes to VBScript. YES! I said this one goes to VBScript. But, WAIT A SECOND! PowerShell can provide some leverage when you combine these two scritping technologies. Again, it’s all about integrating technologies to help you be productive and efficient at work.

Let’s cut to the chase and here’s the low down. Many you have been wondering How Can I Automate my Telnet session? Well, VBScript have provided some means to do this for some time. Now, I can use PowerShell to make it more pretty.

Here’s the sample VBScript code use to send commands to a Telnet session: (keep in mind, I’m connecting to Microsoft Telnet in this scenario)

[sourcecode language=”vbscript”]
set oShell = CreateObject("WScript.Shell")
oShell.run("Telnet")
WScript.Sleep 1000
oShell.SendKeys("Open 127.0.0.1 23")
WScript.Sleep 1000
oShell.SendKeys("{Enter}")
WScript.Sleep 1000
oShell.SendKeys("n")
WScript.Sleep 1000
oShell.SendKeys("{Enter}")
WScript.Sleep 1000
oShell.SendKeys"MyName"
WScript.Sleep 1000
oShell.SendKeys("{Enter}")
WScript.Sleep 1000
oShell.SendKeys("MyPassword")
WScript.Sleep 1000
oShell.SendKeys("{Enter}")
WScript.Sleep 1000
oShell.SendKeys("MyCommand")
WScript.Sleep 1000
oShell.SendKeys("{Enter}")
WScript.Sleep 1000
[/sourcecode]

This is, in it basic form,  and with no complexity. Now, using PowerShell we can make it a little more functional by automating the process. I decided to add a text file containing a list of Telnet commands I want to automatically execute during my session. Then, I created a PowerShell function that will build and then execute my auto-generated VBScript.

My command list text file “cmdlist.txt” contains 2 commands for testing purpose and it’s stored in my C:\Temp folder:
Help
Exit

Now, Here’s my “Connect-MyTelnet” function (in its basic form) prototype which put everything together:

[sourcecode language=”powershell”]
function Connect-MyTelnet{
Param(
[string] $IPAddress,
[string] $Port,
[string] $UserName,
[string] $Password,
[string] $cmdlistPath
)
## – Setting default values:
if($port -eq $null){ $Port = "23"; };
if($cmdlistPath -eq $null) { $CmdlistPath = ‘c:\temp\cmdlist.txt’; };

## create vbscript file: MyTelnetSession.vbs
## – For Microsoft Telnet:
$MyVBScript = @"
set oShell = CreateObject("WScript.Shell")`r`n
oShell.run("Telnet")`r`n
WScript.Sleep 1000`r`n
oShell.SendKeys("Open $IPAddress $Port")`r`n
WScript.Sleep 1000`r`n
oShell.SendKeys("{Enter}")`r`n
WScript.Sleep 1000`r`n
oShell.SendKeys("n")`r`n
WScript.Sleep 1000`r`n
oShell.SendKeys("{Enter}")`r`n
WScript.Sleep 1000`r`n
oShell.SendKeys("$UserName")`r`n
WScript.Sleep 1000`r`n
oShell.SendKeys("{Enter}")`r`n
WScript.Sleep 1000`r`n
oShell.SendKeys("$Password")`r`n
WScript.Sleep 1000`r`n
oShell.SendKeys("{Enter}")`r`n
WScript.Sleep 1000`r`n
"@;

## – Get file with telnet commands:
[array] $Cmdlist = Get-Content $cmdlistPath;

## loop through and build each telnet command line:
foreach($cmd in $cmdlist)
{
## – Build VBscript lines:
$MyVBScript += ‘oShell.SendKeys("’+$cmd+’")’+"`r`n";
$MyVBScript += "WScript.Sleep 1000`r`n";
$MyVBScript += ‘oShell.SendKeys("{Enter}")’+"`r`n";
$MyVBScript += ‘WScript.Sleep 1000’+"`r`n";
}

## – Close Telnet Session:
$MyVBScript += ‘oShell.SendKeys(" QUIT")’+"`r`n";
$MyVBScript += "WScript.Sleep 1000`r`n";
$MyVBScript += ‘oShell.SendKeys("{Enter}")’+"`r`n";
$MyVBScript += ‘WScript.Sleep 1000’+"`r`n";

## – Save and execute generated VBscript:
$MYVBScript | Out-File -FilePath c:\temp\MyTelnet.vbs -Encoding ASCII;
& c:\temp\MyTelnet.vbs
}; Set-Alias ct Connect-MyTelnet;

[/sourcecode]

Save the above code as a “Connect-MyTelnet.ps1”, then to load in PowerShell use the “. ./Connect-MyTelnet.ps1″ from the folder you saved the file. Finally, to execute run the following one-liner:

[sourcecode language=”powershell”]
Connect-MyTelnet `
-IPAddress ‘127.0.0.1’ `
-Port 23 -UserName Max `
-Password ‘$mypasword1!’ `
-CmdlistPath c:\temp\cmdlist.txt;

[/sourcecode]

This will create/execute the vbscript that will open a Microsoft Telnet session and submit a series of Telnet commands. Now you got something to work and play.

Bonus!!

If you want to use “PuttyTel.exe” just substitute the PowerShell VBscript code to the following:

[sourcecode language=”powershell”]
## – For PuttyTel:
$MyVBScript = @"
set oShell = CreateObject("WScript.Shell")`r`n
oShell.run("c:\temp\PuttyTel")`r`n
WScript.Sleep 1000`r`n
oShell.SendKeys("$IPAddress")`r`n
WScript.Sleep 1000`r`n
oShell.SendKeys("{Enter}")`r`n
WScript.Sleep 1000`r`n
oShell.SendKeys("$UserName")`r`n
WScript.Sleep 1000`r`n
oShell.SendKeys("{Enter}")`r`n
WScript.Sleep 1000`r`n
oShell.SendKeys("$Password")`r`n
WScript.Sleep 1000`r`n
oShell.SendKeys("{Enter}")`r`n
WScript.Sleep 1000`r`n
"@;

[/sourcecode]

PowerShell V3.0 Object difference vs V2.0…?

I was unconsciously doing something while coding in PowerShell V3.0 Beta, and it caught me off guard.  As I’m getting more comfortable working with PowerShell Objects, I didn’t realized there is an enhancement in place.  There’s a quick way to access with your objects values. I’m trying to scripting for PowerShell V2.0 but I started see errors, then I realize I was accessing my items differently in PowerShell V3.0.

Let me show some PowerShell V3.0 code that access a SQL Server SMO collection of type “Microsoft.SqlServer.Management.Smo.Information”.  I want to access the values of the property “Properties” in the SQL Server Information SMO Object.

*hint*: Remember to use the command “Get-Member” to expose the content (method & properties) in your PowerShell variable.

[sourcecode language=”powershell”]

## – Load Assembly and create your SQL object:
[System.Reflection.Assembly]::loadwithPartialName("Microsoft.SQLServer.SMO");
$MySQL = New-Object(‘Microsoft.SqlServer.Management.SMO.Server’);

## – Getting to your Information Properties"
$MySQL.Information;
$MySQL.Information.Properties;

[/sourcecode]

The last two lines will give you some results back. Now, try the next line:

[sourcecode language=”powershell”]

## – Only valid in PowerShell V3.0:
$MySQL.Information.Properties.name;

[/sourcecode]

This line will display all values in the property “Name”, and that’s great.

Go to another machine with PowerShell V2.0, and execute the lines:

[sourcecode language=”powershell”]

## – Load Assembly and create your SQL object:
[System.Reflection.Assembly]::loadwithPartialName("Microsoft.SQLServer.SMO");
$MySQL = New-Object(‘Microsoft.SqlServer.Management.SMO.Server’);

## – Only valid in PowerShell V3.0:
$MySQL.Information.Properties.name;

[/sourcecode]

Notice you will not get any results back.

Now, change the line below and the execute:

[sourcecode language=”powershell”]

## – Valid in both PowerShell V3.0 and V2.0:
$MySQL.Information.Properties | Select name;

[/sourcecode]

And, it will display all values from this property.

As you notice, using PowerShell V3.0 can list items from the collection without forcing you to pipe “|” the value to another command (“.. | Select Name ..“). Just be careful and make sure the code stay compatible with PowerShell V2.0.

I like this enhancement!

Getting BizTalk information with PowerShell

As I keep venturing into Biztalk, here’s how you can start using PowerShell to access your BizTalk objects with just a few lines of code and (for now) using one of the BizTalk .NET assemblies that’s loaded during the installation.

In the following example, I will create a PowerShell .NET object containing information about my BizTalk Application Artifacts. Please, pay attention to these sample code. There’s lots of information in it.

Open a PowerShell Console prompt, and type (or copy/paste) the following code:

[sourcecode language=”powershell”]

## – Load the following Assembly:
[System.Reflection.Assembly]::loadwithPartialName("Microsoft.BizTalk.ExplorerOM");

## – Create a new empty variable to stored the .NET information:
$BTSexp = New-Object Microsoft.BizTalk.ExplorerOM.BtsCatalogExplorer;

## – Now, this line will connect to your Biztalk Local instance:
$BTSexp.ConnectionString = "Server=.;Initial Catalog=BizTalkMgmtDb;Integrated Security=SSPI;";

[/sourcecode]

Now, keep in mind, you need to execute this block of code in your BizTalk server box, or use PowerShell Remoting feature. To look into the newly created object ‘$BTSexp’, use the “Get-Member” command to expose all the .NET object stored in it. You’ll notice both Properties, and Methods:

[sourcecode language=”powershell”]

$BTSexp | Get-member;

[/sourcecode]

As you can see, few line of code,  you got a lot of information about you BizTalk box. Try the following lines to list all our send box:

[sourcecode language=”powershell”]

$BTSexp.Sendports

[/sourcecode]

This line will display all properties and its content on the screen. Now, using the “Get-Member” (or “GM”) command, you can select from these list some of the properties you want to display on screen:

[sourcecode language=”powershell”]
## – List all Biztalk .NET object properties and methods:
$BTSexp.SendPorts | gm;

## – Display some of the selected properties:
$BTSexp.SendPorts | Select Application, name, Status | format-table -auto;

## – The End
[/sourcecode]

Oops!! Notice our result is not exactly correct. Our ‘Application’ values are showing with a long .NET Namespace, and our status column got truncated from the list. The ‘Application’ property is another .NET object that contains more information, and is only accessible if you use the ‘Foreach’ loop condition to get to it.

To fix this oneliner, we need to create a loop block so we can go deep into the .NET object of ‘Application’ and extract that information. The example below I added an “if” statement to search for all SendPorts containing the ‘TransportType’ for FTP’s:

[sourcecode language=”powershell”]

## – Load the following Assembly:
[System.Reflection.Assembly]::loadwithPartialName("Microsoft.BizTalk.ExplorerOM");

## – Create a new empty variable to stored the .NET information:
$BTSexp = New-Object Microsoft.BizTalk.ExplorerOM.BtsCatalogExplorer;

## – Now, this line will connect to your Biztalk Local instance:
$BTSexp.ConnectionString = `
"Server=.;Initial Catalog=BizTalkMgmtDb;Integrated Security=SSPI;";
## – Looping through each item in the SendPorts object and display
## – it in the PowerShell console:
$y = 0;
foreach($item in ($BTSexp.SendPorts))
{
if($item.PrimaryTransport -ne $null)
{
if($item.PrimaryTransport.TransportType.Name -match "FTP|Nsoftware SFTP")
{
Write-host "[$($y.ToString("000"))]`t$($item.Application.name)`t$($item.PrimaryTransport.TransportType.Name)`t$($item.Name)";
$y++;
}
}
};

[/sourcecode]

Well, we are getting better now but we can make it look nicer. Adding a few more lines we change the code to store the values generated into a PowerShell PSObject. Finally, we can generate a better formatted result:

[sourcecode language=”powershell”]

## – Load the following Assembly:
[System.Reflection.Assembly]::loadwithPartialName("Microsoft.BizTalk.ExplorerOM");

## – Create a new empty variable to stored the .NET information:
$BTSexp = New-Object Microsoft.BizTalk.ExplorerOM.BtsCatalogExplorer;

## – Now, this line will connect to your Biztalk Local instance:
$BTSexp.ConnectionString = `
"Server=.;Initial Catalog=BizTalkMgmtDb;Integrated Security=SSPI;";

## – Initialize variables:
$y = 0; [Array] $MyNewObject = $null;

#Add each result into our New object:
$MyNewObject = foreach($item in ($BTSexp.SendPorts))
{
if($item.PrimaryTransport -ne $null)
{
if($item.PrimaryTransport.TransportType.Name -match "FTP")
{
#Building your PowerShell PSObject item:
$newPSitem = New-Object PSObject -Property @{
seq = $y.ToString("000");
Application = $item.Application.name;
PortType = $item.PrimaryTransport.TransportType.Name;
Port = $item.Name;
};
#To display PSObject item values while processing:
$newPSitem;
$y++;
}
}
};
$MyNewObject | Select seq,Application,PortType,Port | ft -auto;

[/sourcecode]

Now, we’ve created a new PowerShell object with our selected properties, and with a new output that looks Great!. Just Try It in your box!!

The above script will list all FTP related ports. Here’s another the same code PowerShell script for listing all SendPorts on your BizTalk Server:

[sourcecode language=”powershell”]

## – Load the following Assembly:
[System.Reflection.Assembly]::loadwithPartialName("Microsoft.BizTalk.ExplorerOM");

## – Create a new empty variable to stored the .NET information:
$BTSexp = New-Object Microsoft.BizTalk.ExplorerOM.BtsCatalogExplorer;

## – Now, this line will connect to your Biztalk Local instance:
$BTSexp.ConnectionString = `
"Server=.;Initial Catalog=BizTalkMgmtDb;Integrated Security=SSPI;";

## – Initialize variables:
$y = 0; [Array] $MyNewObject = $null;

## – Initialize variables:
$y = 0; [Array] $MyNewObject = $null;

#Add each result into our New object:
$MyNewObject = foreach($item in ($BTSexp.SendPorts))
{
#Building your PowerShell PSObject item:
$newPSitem = New-Object PSObject -Property @{
seq = $y.ToString("000");
Application = $item.Application.name;
PortType = $item.PrimaryTransport.TransportType.Name;
Port = $item.Name;
};
#To display PSObject item values while processing:
$newPSitem;
$y++;
};
$MyNewObject | Select seq,Application,PortType,Port | ft -auto;

[/sourcecode]

Now, you can get a list of all your sendPorts. Don’t be afraid to experiment. You are only querying BizTalk objects using PowerShell.

My next blog will show this query use to list all ReceivePorts.

Happy PowerShelling!!

T-SQL & PowerShell – Another way to Identify Database Snapshots

Just a quick blog on spotting your Database Snaphots. I just couldn’t believe that I’ve been missing creating SQL database snapshots but sometimes having so much work make you blind.  I’ve been using a lot Hyper-V Snapshot features and recently (Thanks to Chad Miller) I got the chance to create and test a few.

So, first we need to create a new db snapshot of my AdventureWorks database using T-SQL Script:

[sourcecode language=”SQL”]
CREATE DATABASE AdventureWorks_dbSnapShot_0001 ON
( NAME = AdventureWorks_Data, FILENAME =
‘C:\Program Files\Microsoft SQL Server\MSSQL11.MSQLDENALICTP3\MSSQL\DATA\AdventureWorks_Data_0001.ss’ )
AS SNAPSHOT OF AdventureWorks;
GO
[/sourcecode]

Now, I go to SSMS and verify my new database snapshot exist by going into the ‘Object Explorer’ and looking under ‘Database Shashots’ folder.

Using T-SQL

If I use the following T-SQL command to list all my databases:

[sourcecode language=”SQL”]
Select * from [sys].[sysdatabases]
[/sourcecode]

I will get all of them listed including the snapshots. So, here’s another way to use T-SQL to identify all database snapshots. For that, I’m going to do a select and use from the Master db the view named “[sys].[databases]”:

[sourcecode language=”SQL”]
SELECT [name]
,[database_id]
,[source_database_id]
,[owner_sid]
,[create_date]
FROM [master].[sys].[databases]
[/sourcecode]

In this result, pay attention to the “[source_database_id]” column. Notice that this column is mostly “null” except when if it has a value. This value will match the “[Database_ID]” column. So, you can use this to identify database snapshots.

Using PowerShell

Now, let’s take a look on how to use PowerShell to identify database snapshots using SMO. In the following code I’m listing all databases but snapshots are also included.

[sourcecode language=”PowerShell”]
Import-Module SQLPS -DisableNameChecking
$MySQL = New-Object Microsoft.SqlServer.management.Smo.Server ‘YourServername\InstanceName’
$MySQL.Databases | Select name
[/sourcecode]

So, in order to identify the database snapshot I need to look deeper into our .NET database object. Using the “Get-Member” command I can see what’s object are available.

[sourcecode language=”PowerShell”]
($MySQL.Databases) | Get-Member | Out-Gridview
[/sourcecode]

Using the “Out-Gridview” command to view my results a separate popup window, I found two properties of interest:

  1. IsDatabaseSnapshot‘ – which show “true” us if is a snapshot.
  2. DatabaseSnapshotBaseName‘ – which give us the origne of database name of the snapshot.

So, now I can use the following PowerShell commands to show all my databases and identify the snapshots:

[sourcecode language=”PowerShell”]
$MySQL.Databases | `
Select name, Owner, RecoveryModel, `
IsDatabaseSnapshot, DatabaseSnapshotBaseName `
FT -AutoSize;
[/sourcecode]

Conclusion

Using both T-SQL and PowerShell examples, now you have a startup point to spot and take some control over your database snapshots.

Happy PowerShelling!

“Windows 8 PowerShell and Hyper-V 3.0 Preview” Slide deck and samples

Last weekend at the “ITPro Camp Saturday” in Sarasota Forida was great event.  Thanks to everyone for participating, and taking the precious time on a Saturday to learn about new and current technologies.  It was a GREAT!!

Here’s my “Windows 8 PowerShell and Hyper-V 3.0 Preview”presentation and demo scripts use during the session:

Please, don’t hesitate to contact me if you have any questions.

Thanks You!

It’s Just Random: PowerShell – Mistery of Redrum Solved!!

It’s Friday and I’m following Jeffery Hicks idea to have fun with PowerShell.  Well, here’s the mistery of Redrum solved one more time.  Some time ago, I remember seen some code for reversing a string of characters.  Well, here’s the one-liner I use to solve the puzzle:

[sourcecode language=”powershell”]
$str = "Redrum";
[System.Array]::Reverse(([Array]$RevStr = $str.ToCharArray()));
foreach($chr in $RevStr){ $mistery += $chr }
$mistery;
[/sourcecode]

That’s all for now…. Have fun with PowerShell!

QuickBlog: PowerShell Automating your Credentials

Back in January, I did a quick blog about “Use PowerShell to submit SQLServicePack job to multiple Server“, in that script I have PowerShell to always prompt me for credentials.  But, after a while of typing over and over my password, I found to way to automate my credentials.   Yes!  By automating the credential step, I just could schedule the job, and have time to work with something else.

In this example, I’m passing my credential to the “Start-Transfer” command, so I can do my file download to my destination folder.  Here’s the code snippet to accomplish the automation:

[sourcecode language=”powershell”]
## – Automate to create your credential:
$MyUserName = "Domain\Username";
$MyPassword =  ConvertTo-SecureString ‘MyPwd001!’ -asplaintext -force;
$MyCredentials = new-object `
-typename System.Management.Automation.PSCredential `
-argumentlist $MyUserName,$MyPassword;

## – Import the module and start the download process of one file:
Import-Module BitsTransfer;
Start-BitsTransfer `
-Credential $MyCredentials `
-Source ‘http://YoufilesSite/Files/Demo01.zip’ `
-Destination ‘\\YourServer\NetworkSharedFolder\Demo01.zip’;
[/sourcecode]

Ha!  I know what you’re think!  I’m hardcoding my password in the scripts.  So, our possible options would be: 1) you’re the only one running this script (don’t tell your boss),  2) You trust your Network security (humm!), or 3) find the way to encrypt the script so no one can guess the password.

There are products like SAPIEN’s PrimalScript and PrimalForms, that will let you create an executable out of your script, and then you can deploy it to your server.  But, then again, only you can make that decision.  I’m just showing that’s possible in case you need it.

Have fun with PowerShell!