Feeds:
Posts

## Out-printer cmdlet

Recently I was asked if you could use PowerShell to print to a specific printer.  I have written posts on how to print to your default printer but had never tried printing to a specific printer.  So I decided I should see if this is possible.

And what do you know there is a built in cmdlet called Out-Printer that accepts the -Name parameter.  Using this optional parameter allows you to specify an alternate printer.

OK so now that I’ve got that lets try it out.  I have a printer here in my office which is an HP 2600 color laserjet printer.  It is NOT my default printer so I would like to test printing to it using that cmdlet.

First lets just test the cmdlet without the optional parameter.

get-process | Out-Printer

Sure enough that prints the get-process output directly to my default printer.

Now lets try

get-process | Out-Printer -name \\Svr1\it-2600n

Sure enough this printed out to the HP 2600 color laser.  PERFECT!!!

Now there are a few problems with this cmdlet, the first being that if you specify the -name parameter and you are trying to print to a shared printer you need to use the UNC name of that printer.

The second problem is that this is a cmdlet that prints output.  It does not print the CONTENT of a file.  So for example if you wanted to print a txt document and you wrote Out-Printer “c:\test.txt” it would actually print out a page with c:\test.txt on it.

You could use the Get-Content cmdlet and pipe that into the Out-Printer cmdlet like this Get-Content “c:\test.txt” | Out-Printer

This would give you a printout of the actual contents of the test.txt file.  However, if you wanted to print a word document or a pdf document this would not work.  It will give you tons of garbage and not the actual file contents.

So you are back to the drawing board again.  To print a word or pdf document you need to use this command.

Start-Process -FilePath “C:\Test.Docx” -Verb Print

Which brings you back to the original issue that was made, how do I print to a printer that isn’t the default one?

And for the moment I have to say I don’t see a way.  I think you need to set the default printer first, then you can use the Start-Process cmdlet and print the document.

## Powershell function to get remote disk space

I was working on a project and needed to remotely check a servers available disk space so I started trying to come up with a simple reusable function to check the disk space.  The following is what I came up with.

Function GetDiskSpace

{
<#
.SYNOPSIS
GetDiskSpace displays the Total Size and Total Free Space of a Remote Computer Drive
.DESCRIPTION
See synopsis
.EXAMPLE
To run – enter GetDiskSpace
#>
$computer = Read-host "Please enter the computer name"$drive = Read-host "Please enter the drive letter including the colon (c:)"
$disk = Get-WmiObject Win32_LogicalDisk -ComputerName$computer -Filter "DeviceID=’$drive’" | Select-Object Size,FreeSpace "Remote computer:$computer drive letter $drive has {0:#.0} GB free of {1:#.0} GB Total" -f ($disk.FreeSpace/1GB),(\$disk.Size/1GB) | write-output

}
Set-alias GDS GetDiskSpace

## Installing WordPress on Windows Server 2008 R2

I recently got involved with a new website project and was trying to determine the best set up for our situation. I needed a Content Management System (CMS) so the end user could make the changes to the site without my intervention. So, I started looking into different solutions. My first attempt was DotNetNuke community edition. Since I am familiar with both MS SQL and ASP.NET I thought this would be the most logical choice. So, I set up a virtual machine running Windows Server 2008 R2 and set to work configuring DotNetNuke.

After a bit of wrangling I was able to get the site up and running with the DNN sample site running. It was pretty slick but there were a lot of confusing configuration settings. I was able to get a basic sample site running and let the end user mock up a few pages. It worked but it wasn’t great.

So, I remembered that I also have a BlogEngine.net site running on MSSQL and ASP.NET so I looked into that as well. Again not bad, but nothing I would say I absolutely loved.

Now, I am setting up another virtual machine and going through the steps of setting up a Windows installation of WordPress.

I found a great step by step tutorial from someone else that has helped me get up and running. http://www.vsysad.com/2012/04/create-a-wordpress-blog-on-windows-server-2008-r2-iis-7-5-and-mysql/

Now that the site is up and running I can choose a template and begin to customize the site.

So far, I have to say I am more comfortable with WordPress as a CMS and it seems easier to work with than the other systems I have tried. Of course the next big trick would be to create my own custom theme.

## Merry Christmas

Merry Christmas to all! Hope it was a special day for everyone.

## Repairing Windows Cluster Server

This past weekend I was rebuilding a storage array to increase the storage capacity and also reconfigure the drives to optimize the arrangement for better performance on our SQL Server.  The original arrangement was two Dell PowerEdge 1950 servers connected to a  Dell MD3000 Storage array.  This setup was using Windows Server 2003 Clustered for High Availability.  We had a single Raid 5 array in the MD3000 and on it were three partitions, one for the Quorum, One for Data and one for Log files.

Our new configuration was designed to increase the drive space and also split off the partitions onto separate raid arrays.  So, we created a RAID 10 for the Log Files, a RAID 5 for the Databases, and then another Raid 10 which contained the Quorum partition and also a partition for the Temp DB.

When we brought up the server after the reconfiguration we discovered that the Cluster Service would not start.  This was due to the fact that the Quorum drive had been moved and was no longer at the location that Cluster Service expected it.

After several minutes of searching I found this TechNet article http://technet.microsoft.com/en-us/library/cc738770(v=ws.10).aspx.  Basically, in order to start up the Cluster Service without the Quorum resource you need to edit the service and put in a switch.

Edit the ClusterService and add “/fixquorum” as a startup parameter and then start the service.  Once the service has started up with the /fixquorum option you can then run clusterrecovery.exe.  Clusterrecovery.exe will allow you to substitute a new disk for the Quorum disk.  Once you have done that and its replaced the quorum disk you will then be able to restart your ClusterService with the /fixquorum option and it should start up correctly.

Cheers!

## Using Proxies in SQL Server Agent

Have you ever had to run a job in SQL Server Agent and needed it to run with different permissions than the login that runs SQL Agent?  I have come across this a few times.  Most recently, I was trying to run a SSIS Package as a SQL Agent Job and one step of the job was trying to launch WinSCP as part of an “Execute Process Task”.  The task was able to run and could launch WinSCP but it was running with the credentials as the SQL Agent Service.

The problem with that was that WinSCP stored their sessions in the registry as part of HKey\Current_User.  So, when the job launched using the SQL Agent Service Account, it could not access the values in the registry because it didn’t have the stored session in its hive.

Now, I know there are a few ways to fix this issue but I wanted to choose setting up a SQL Proxy.  A SQL Server Agent proxy gives the SQL Server Agent access to the security credentials for a Microsoft Windows User, which is to say it allows the Agent to impersonate a user when it runs that step of the job.

There are a few steps to using a Proxy.  First you need to set up Credentials in SQL Server Management Studio.  A credential is a record that contains the authentication information for connecting to resources outside of SQL.

Here are the steps to create a credential.

In SSMS Object Explorer open the Security folder and right click on Credentials and choose “New Credential.

Once you open the New Credential window you are given the option to Name the credential. This can be anything you want to call it. Its for your reference. Choose something that will make sense to you.

Then in the Identity field type the name of the account you are going to use. I used a domain account so when I filled it in I put the format DOMAIN\UserName.

Then I typed the password and typed it again to confirm and clicked OK.

Now you are ready to use these credentials in creating a Proxy.

In Object Explorer scroll down to the “SQL Server Agent” and expand the folder.

Then go to Proxies.  In my example I need to be able to run command line applications so I choose the “Operating System (CmdExec) Proxy.

Right click on the proxy you want to use and choose “New Proxy”.

Once again you are given a window where you enter the name, and description for the new proxy.  Then you select the “Credential name”  by clicking on the three dots.

After that you just select the options for what this proxy is allow to access.  A good explanation of what each subsystem is can be found here http://msdn.microsoft.com/en-us/library/ms187100(v=sql.105).aspx

Once you have clicked OK you should now be able to use the Proxy in your SQL Agent Job.

Just go to the pull down for “Run As:” and select your new Proxy.
That is all there is to it.  Now your SQL Agent Job will run that step using the credentials you’ve supplied.

## Using PowerShell to query Active Directory

I recently needed to find all disabled computers in my Active Directory Installation.  So, rather than open up Active Directory Users and Computers and manually search through multiple OU’s and create a list I decided to use PowerShell.

So, I started playing around with the command Search-ADAccount

Using Get-Help Search-ADAccount I am able to determine that the syntax for a query is fairly simple.  There are several switches for the command all of which are self explanatory.

-AccountDisabled

-AccountExpired

-AccountExpiring

-AccountInactive

-LockedOut

So, my first reaction was to run the command

Which returned a long list of items with more information than I needed and in a format that was very hard to read.

AccountExpirationDate :
DistinguishedName     : CN=Guest,CN=Users,DC=DOMAIN,DC=com
Enabled               : False
LastLogonDate         :
LockedOut             : False
Name                  : Guest
ObjectClass           : user
ObjectGUID            : 1e4955ce-df97-4ecc-8a46-f4356ba2e6cc
SamAccountName        : Guest
SID                   : S-1-5-21-1058032114-1936565697-1108674531-501
UserPrincipalName     : guest@DOMAIN.COM

My next addition to the command was to pipe the results to Format-Table to make it easier to read.

This was much better, now I could see that my list not only included computers but users as well.  I didn’t want the users so I needed to look for another switch for the Search-ADAccount command.  Tada!  I found the switch –ComputersOnly which gives me exactly what I needed.  But now I only want to see some of the columns in my table so lets modify the command a little more.

Search-ADAccount –AccountDisabled -ComputersOnly | Format-Table –AutoSize Name, LastLogonDate, DistinguishedName

This is perfect, now the results are readable and I can easily determine what computers in my environment are Disabled.

 Name LastLogonDate DistinguishedName AUX-2B CN=AUX-2B,OU=OLD Computers,DC=DOMAIN,DC=com TECH-GC 10/5/2010 4:11:36 PM CN=TECH-GC,OU=OLD Computers,DC=DOMAIN,DC=com TS-2 8/19/2010 5:40:54 PM CN=TS-2,OU=OLD Computers,DC=DOMAIN,DC=com WPIX CN=WPIX,OU=Newark,DC=DOMAIN,DC=com CITRIX 5/5/2010 9:46:26 PM CN=CITRIX,OU=OLD Computers,DC=DOMAIN,DC=com SERVER-TEST 6/3/2010 7:16:24 PM CN=SERVER-TEST,OU=OLD Computers,DC=DOMAIN,DC=com ARCHIVE2 9/1/2010 11:36:09 AM CN=ARCHIVE2,OU=OLD Computers,DC=DOMAIN,DC=com ACCT-USR2 CN=ACCT-USR2,OU=OLD Computers,DC=DOMAIN,DC=com TECH-GC7 6/2/2011 12:24:32 AM CN=TECH-GC7,OU=OLD Computers,DC=DOMAIN,DC=com TECH7-GC 4/9/2012 8:35:46 PM CN=TECH7-GC,OU=OLD Computers,DC=DOMAIN,DC=com

At this point I now have all the computer accounts in my Active Directory that are disabled.  And it took me all of about a minute to type out the command and hit return.  Much more efficient than going through AD manually and looking.

At this point I could manually go into AD and remove the accounts but since I am already in PowerShell all I need to do is change the command slightly and I could remove those accounts in a flash.  To do this I need to pipe this to another command and remove them