The Multifunctioning DBA


November 5, 2008  9:37 PM

Exchange Quota Management

Colin Smith Colin Smith Profile: Colin Smith
Exchange Server ActiveSync

One of our Mail Administrators is new to the world of Exchange as we are currently migrating from Lotus Notes. She is also new to the world of scripting but is eager to learn how to administer exchange using Powershell. I sat with her today and we walked through a simple example of how to set quotas for user mailboxes. Here is what we did:

 

$names = Import-Csv “path to csv file containing first and last names”

foreach($name in $names)

{

$first = $name.first

$last = $name.last

$identity = “$last, $first”

set-mailbox `”$identity`” -issuewarningquota 180mb

get-mailbox `”$identity`”

}

 

So let’s break this down a bit.

  1. I had the mail admin get a list of all the users and put them In a csv file with the headers of first, last
  2. We bring that in and assign the variables $first and $last
  3. I then create the $identity variable and assign that with $last, $first so it would look like ‘Smith, John’
    1. This is so we modify the correct mailbox
  4. Then I use the exchange commandlet set-mailbox and pass it the $identity variable and the parameters that I want to change.
    1. In this case only the issuewarningquota parameter is being modified.
  5. Then I do a get-mailbox for the same $identity and I pipe that to format-table and look at the name and the parameter that I just modified in order to make sure that it has been set correctly.

That is it. It is so easy to make these changes to a huge number of users. If you have any questions or comments please let me know. Also if you would like to drop me a line head over to http://sysadminsmith.com and submit a question.

October 30, 2008  9:09 PM

Powershell Schedule Task

Colin Smith Colin Smith Profile: Colin Smith
Exchange Server ActiveSync

I have a couple Powershell Scripts that I have written that do something useful for me, the problem is that these are useful to me because I am asleep when I usually want them to run. I thought it would be a good Idea to write another script that would put these into the Windows Task Scheduler for me. This way I do not have to go log into the server and schedule them manually every time I want them to run. Also I have the ability to run Powershell on my PDA, so it will be nice to be able to do this from anywhere using my phone.

I dug into this and found that I certainly could use Powershell and WMI to look at jobs, create new jobs, modify jobs, and delete jobs. I thought this is great and I started coding. First I just wanted to pull a list of the jobs that are currently set up. When I did this I got no results. I started looking into this and found that Powershell cannot see jobs that were created with the Windows GUI and that the GUI can not see jobs that have been created or modified by Powershell. This is not cool and I am still not happy with this. I did, however find a way to complete my task.

Microsoft has another tool called schtasks.exe that will do the trick for us. If you need some more information on how to use this tool check out this TechNet Article about it. I decided that I would use this in my Powershell scripts to get my tasks set up. Here is what I did:

schtasks /delete /s pni-vmdbasql /TN “Job Name”

$st = Read-Host “`nWhat time, in 24:00:00 format, would you like to disable monitoring?”

$sd = Read-Host “`nWhat Date would you like to run this? mm\dd\yyy format please”

schtasks /create /TN “Job Name” /S remote-servername /RU domain\username /RP user password /SC Once /ST $st /SD $sd /TR Job to run

echo
“Complete”

schtasks /query /S Remote-servername

That is really all you need to do in order to set up a job to run once at a given time. After I complete setting the job up I query the tasks in order to verify that what I have just done is actually set up. Hope this will help someone out. If you have any questions or comments please let me know by leaving a comment here or check out my site at sysadminsmith.com.


October 28, 2008  11:06 PM

Powershell Email

Colin Smith Colin Smith Profile: Colin Smith
Exchange Server ActiveSync

The other day I was out reading some blog posts and I ran across one that talked about needing to send an email to a ridiculous number of people. So many that they could not all be fit into the to and cc fields of Outlook. So I thought why not Powershell this. All you would need is a listing of the email addresses that you want to send the mail to and then a file that contains the body of the email. For the addresses I would hope that you have them in your contacts and then you can do an export to a file. Once you have that then type the body of the email into a file and now lets write a script to send it.


$users = get-content “path to file with listing of email addresses”

foreach ($user in $users)

{

$smtpServer = “name of smtp server to send mail”

$smtp = New-Object Net.Mail.SmtpClient($smtpServer)

$emailFrom = “yourname@yourdomain.com”

$subject = “Some Subject Line”

foreach ($line in Get-Content “Path to file with body of email”)

{

$body += “$line `n”

}

$smtp.Send($EmailFrom,$user,$subject,$body)

}

}

So there you go. No limit on how many users this script will send the mail to. Any questions or comments please let me know and also goto sysadminsmith.com to drop me an email.


October 28, 2008  5:59 PM

MS SQL Server Monitoring Part 3

Colin Smith Colin Smith Profile: Colin Smith
Exchange Server ActiveSync

In MS SQL Server Monitoring Part 2 we talked about inserting the Marker into the ERRORLOG file. Now that we know we can do that we need to look at how we can scan the ERRORLOG file for errors, and only new errors that we care about. I do not know about you but I do not want to get a notification every time I get a logon failure. I only want to know about important events such as backups failing, severe errors, and mirroring failures. You can change things so you are notified about anything you would like though. This script was put together in such a way that it is easily customizable for anything you would like.

Here is the code for the Get_Errors function of the script. I am going to highlight some things but this will not get very indepth at this time. I would be happy to give a more indepth look into the code if you like though. Just let me know here or at my site sysadminsmith.com.

###########################################

function Get_Errors

###########################################

{

#Echo “Get Errors”

$ignore = get-content “h:\$folder\ignore_strings”

$estrings = Get-Content “h:\$folder\Error_Strings”

$i = 0

$n = 0

$descript = 0

$mark = 0

foreach ($line in $log)

{

if ($line -like “*Monitor Marker*”)

{

$i ++

}

}

foreach ($line in $log)

{

if ($descript -eq 1)

{

Echo $line >> “H:\$folder\monitor.out”

$descript = 0

}

if ($line -like “*Monitor Marker*”)

{

$n ++

}

#if (($n -ge $i) -and ($line -like “*Error*”) -and ($line -notlike “*logon*”))

if ($n -ge $i)

{

$ignoreit = 0

foreach ($estring in $estrings)

{

if ($line -like “*$estring*”)

{

$ignoreit = 0

foreach ($istring in $ignore)

{

if ($line -like “*$istring*”)

{

$ignoreit = 1

}

}

break

}

else

{

$ignoreit = 1

}

}

if ($ignoreit -eq 0)

{

$mark = 1

$descript = 1

echo $folder >> “H:\Alert\Alert”

if (!(test-path “H:\$folder\monitor.out”))

{

New-Item -type File “H:\$folder\monitor.out”

}

Echo $line >> “H:\$folder\monitor.out”

}

}

}

if ($mark -gt 0)

{

First I get the Ignore_strings and the error_strings. The error_strings is what I use to determine if the line I am looking at in the ERRORLOG file is important enough to evaluate further. If no Error_string is found on that line then I just move on. The Ignore_strings are words or phrases that would make a line not important to me even if I did find a word or phrase that is in Error_strings. This is how I can control what errors are important to me and what ones are not. Then a couple more variables for flow control. Then I can get into the meat of the function. I start in and look at the ERRORLOG. This time I am only looking for the Monitor Marker that I have put into the ERRORLOG last time I found an error. So I count everytime I see Monitor Marker and put that into a variable. Once I have looked through the entire file and have a good count of the Monitor Marker entries I then start again. This time I again count Monitor Marker until this count is equal to the previous count. Once it is equal then I know that every line from here on out I need to look for anything that is my error_strings file. If I find any lines that have any of my error words in them I then also look for any of the ignore words in that line. If I do not find any ignore words then I output the error line to a file and I also get the next line in ERRORLOG since that is really where the important data is held. I do that for every line left in the ERRORLOG file. This way if more than one error has occurred I will be notified of them all. If I have found any errors I then input a Monitor Marker into the ERRORLOG by doing what I talked about in MS SQL Server Monitoring Part 2.

This pretty much covers how I am looking for and extracting the Errors out of the ERRORLOG. Next time we will discuss how to notify someone about the errors. I hope that this has been helpful and informative. If you have any questions or comments please leave them here or head to sysadminsmith.com and leave me an email, I will be happy to discuss this further with you.


October 26, 2008  1:25 AM

Powershell Date Math

Colin Smith Colin Smith Profile: Colin Smith
Exchange Server ActiveSync

A few years ago my company wanted me to write a script to enforce a active directory policy that dealt with user accounts. They wanted all accounts that had not been used in 90 days to be automatically disabled and after not being used for 180 days the account to be deleted. In order to do this I had to do some Date Math. This was before I was introduced to Powershell so I had to do it in VBScript. Now I am interested in Date Math using Powershell because our ITSEC officer calls me a couple times a year and questions if the script is working or not. Just so you now the script has been correct every time. Anyway, when she calls I always have to do the math on my own to determine if the script was correct in its action or inaction. I have done a Powershell script that will do this math for me. IT is a really easy script and I am sure that it will come in useful when I get called about my 90-180 script as well as some other times. It was well worth the 5 minutes that it took to sit down and write. So here we go.


############################################################################

## Get current date and add or subtract number of days and show that date ##

############################################################################

## Find out from user how many days they want to look forward or back

$date = [datetime]::Now

Echo “`nThe current date is $date`n”

$days = Read-Host “How many days? This will show you x days ago and x days from now.”

$futuredate = [datetime]::Now.AddDays($days)

Echo “`nThe date $days days from now is $futuredate”

$pastdays = -$days

$pastdate = [datetime]::Now.AddDays($pastdays)

echo “`nThe date $days days ago was $pastdate`n”

###########################################################################

As you can see this is a very short and easy script. So here is what I am doing. First I load the variable $date with the current date with the [datetime]::now. Now I go ahead and echo that out just so we know the current date. If you are like me, you are always looking to the bottom right of your start bar to find the date. Now I ask the user using the read-host cmdlet how many days back and forward that they would like to see the dates for. I load that into $days. Now I load $futerdays by using [datetime]::now.adddays($days) function. Then I can echo that date out. Then I just repeat the process by loading $pastdate with the current date added with the negative value of $days. Here is what the output of the script looks like.


PS E:\New Scripts> .\Dateplusminus.PS1

The current date is 10/25/2008 18:24:02

How many days? This will show you x days ago and x days from now.: 30

The date 30 days from now is 11/24/2008 18:24:07

The date 30 days ago was 09/25/2008 18:24:07

If you have any questions or comments about this please let me know by leaving a comment or heading over to sysadminsmith.com and sending me a email.


October 24, 2008  6:14 PM

Powershell: Verify SQL Server is running

Colin Smith Colin Smith Profile: Colin Smith

I call this Pinging the SQL Server. I am just going to make a connection to verify that the server is running and then close the connection. This is something that I am running in conjunction with the SQL Server Monitoring that I am posting about on this blog as well. I did not build this directly in but you could if you want to. This is mostly done separate because I run the monitoring script on the local host whenever possible. If I have a problem on the Local Host of the SQL Server then I will never know. This script runs from another server that is used primarily for monitoring other servers and should have essentially no downtime. So I run this every ten minutes to verify that my SQL Servers are up and that I can make a connection to the server. Essentially I am pinging the SQL Server. I have also built in a piece that will verify the server is actually down by waiting until the second failed ping in a row before sending out notifications. On multiple occasions this script has notified us of a server being down and we find that it is actually a problem with the Server or host OS and not SQL Server. My company does have MOM in place but us DBA’s almost always know about a problem on one of our SQL Servers before the Windows Administration team.

##Ping SQL Servers
function Set_Pagers
{
##Check Day and Time for Pager_Day or Pager_Night and if Pager_Night check if server is Test or Prod
$time = Get-Date -displayhint time
$day = Get-Date -uFormat “%A”
Clear-Content i:\$folder\mailout.txt
cd h:
if (($time -gt “7:00:00 AM”) -and ($time -lt “4:00:00 PM”) -and ($day -ne “Saturday”) -and ($day -ne “Sunday”))
{
Get-Content “i:\$folder\Pagers_Day” >> “i:\$folder\mailout.txt”
Get-Content “i:\$folder\email” >> “i:\$folder\mailout.txt”
$pager = Get-Content “i:\$folder\mailout.txt”

}
else
{
if ($torp -eq “Prod”)
{
Get-Content “i:\$folder\Pagers_night” >> “i:\$folder\mailout.txt”
Get-Content “i:\$folder\email” >> “i:\$folder\mailout.txt”
$pager = Get-Content “i:\$folder\mailout.txt”
}
else
{
Get-Content “i:\$folder\email” >> “i:\$folder\mailout.txt”
$pager = Get-Content “i:\$folder\mailout.txt”
}

}
}
#################################
####### Start Script ############
#################################
$time = Get-Date -displayhint time
New-PSDrive i -PSProvider filesystem -Root \\pni-vmdbasql\D$\Monitoring
Clear-Content -Path i:\functions\OUT\Pingservers.out
##Read in List of SQL Servers and open a connection
##If no connection can be established send out notifications.
$servers = Import-Csv -Path “i:\inputs\sqltab.txt”
foreach ($server in $servers)
{
$machine = $server.server
$instance = $server.instance
$torp = $server.torp
$ping = $server.ping

if ($instance -eq “NULL”)
{
$SqlServer = $server.server
$folder = $server.server
}
else
{
$SqlServer = “$machine\$instance”
$folder = “$machine-$instance”
}

if ($ping -eq “Y”)
{
if (!(test-path “i:\$folder\pingfail.txt”))
{
New-Item -type File “i:\$folder\pingfail.txt”
}
$failcountfile = “i:\$folder\pingfail.txt”
$failcount = Get-Content “i:\$folder\pingfail.txt”

$SqlServer
$SqlCatalog = “master”
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = “Server = $SqlServer; Database = $SqlCatalog; Integrated Security = True”
$SqlConnection.Open()
if($SqlConnection.state -eq “Open”)
{
echo “$sqlserver – Connection Succesfull at $time” >> i:\functions\OUT\Pingservers.out
Clear-Content $failcountfile
#echo “connection Succesfull” >> i:\PS_Scripts\Files\Pingservers.out
$SqlConnection.Close()
echo “Succes”
}

else
{
echo “$sqlserver – No connection could be established at $time” >> i:\functions\OUT\Pingservers.out
if ($failcount.length -gt 0)
{
#echo “No connection could be established” >> i:\PS_Scripts\Files\Pingservers.out
echo “Fail at $time” >> $failcountfile
echo “Fail $sqlserver”
echo “Setting Pagers”
Set_Pagers
Echo “Notify DBA”
.{I:\Functions\Ping_Notify.ps1}
}
else
{
echo “Fail at $time” >> $failcountfile
}
}
}
if ($ping -eq “N”)
{

echo “$sqlserver – is not being pinged at this time. Check SQLTAB” >> i:\functions\OUT\Pingservers.out
}

}

So let’s walk though this and see what is going on. Again this will be a high level overview of what I am doing so please feel free to ask questions if needed. The first part of the script reads in my sqltab file. We talked about this file in the SQL Server Monitoring discussion and I am using the same file here. This file contains all the pertinent information about all of the SQL Servers in the company. Once the script gets all the needed variables set I can attempt to connect to the server. I look in the sqltab file and if the server is set up to be pinged, we may shut this off for maintenance windows where we know the server will be offline, then it will continue to make a connection. If that connection is successful then I write that to a log file for future reference.

If the connection fails, then I need to know about this. I log the connection failure in the same historical log file for the future and I also check a failcount file for this server. If this is the first time the connection for this server has failed then I just make note of it in that file as well and continue on going through the list of servers to ping. If the server has failed the previous time then I need to make someone aware of the outage. I then call another function called Ping_Notify.ps1. This script is what will notify the appropriate people of the issue. This will continue to send notifications every ten minutes until the server pings successfully. You will notice that if the ping is successful I also clear-content on the failcount file for that server. That way no more notifications will be sent out for this server.

Again this is a very high level overview of what I am doing. If you have any questions comments or suggestions please let them be known. If you would like to email me just head over to my web site at sysadminsmith.com and let me know.


October 23, 2008  9:58 PM

MS SQL Server Monitoring Part 2

Colin Smith Colin Smith Profile: Colin Smith
Exchange Server ActiveSync

OK so in MS SQL Server Monitoring we left off asking about how we can insert a Marker into the ERRORLOG file while the SQL Server is running and the SQL Server has the file locked. Actually, the answer is pretty simple it is the how that is more problematic. So the solution is to have the SQL Server input the line that we want into the ERRORLOG for us. This can be done with a SQL query as follows:

raiserror (‘Monitor Marker’, 1, 2) With Log

That is simple enough but now we need to figure out how to get Powershell to do that for us. In order to do this I did the following:

##########################################

#####    Enter Monitor Marker    ##########

##########################################

        $monitorfile

        Echo “Error log $errorlog”

        Echo “Echo Monitor Marker”

        if ($errorlog -ne $monitorfile)

{

            Echo “Monitor Marker” >> $monitorfile

        }

        else

{

            $sqlquery = “raiserror (‘Monitor Marker’, 1, 2) With Log”

            $SqlCatalog = “master”

            $SqlConnection = New-Object System.Data.SqlClient.SqlConnection

            $SqlConnection.ConnectionString = “Server = $SqlServerString; Database = $SqlCatalog; Integrated Security = True”

            $SqlCmd = New-Object System.Data.SqlClient.SqlCommand

            $SqlCmd.CommandText = $sqlquery

            $SqlConnection.Open()

            $SqlCmd.Connection = $SqlConnection

            $SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter

            $SqlAdapter.SelectCommand = $SqlCmd

            $DataSet = New-Object System.Data.DataSet

            $SqlConnection.Close()

            $SqlAdapter.Fill($DataSet)

            ##########################################

        }

    }

That is the function within my monitoring script that enters the Marker into the ERRORLOG for me. This only runs and enters the Marker if I have found an error since the previous time that monitoring ran. I run the monitoring script every ten minutes so that I know almost as soon as an error occurs.

Now that I know I can get a Marker of some sort into the ERRORLOG now I need to make sure that I can parse the ERRORLOG file and look for only meaningful errors and only ones that have not been dealt with already. This gets a bit tricky since I could not find a way to read the file from the bottom up to the last Monitor Marker. This is really the only part of the script that I think is a bit sloppy and if anyone knows a better way to do this then please let me know. In order to get only the new errors that I am interested in I have to parse the file two times every time the script runs. Once to count the number of Markers in the file and the other to find errors after the last Marker. I know this is not the cleanest way but it is the best I can do at this time. It still runs very quickly and does not have a problem finishing in well under one minute. We will again pick up here next time and we will go over that section of code. Please let me know if you have any questions about this or ideas on how to fix my double parsing issue. You can also check out my site at sysadminsmith.com and drop me an email if you like.

See MS SQL Server Monitoring Part 3


October 23, 2008  8:30 PM

ASE15 Stack Size

Colin Smith Colin Smith Profile: Colin Smith

I am currently working on upgrading one of our applications from ASE12.5 to ASE15 and the developers are in the middle of testing. This morning I got a call saying that the developer working on this could no longer connect to the server. I looked into it and found that the server was shutdown. I started it back up and started working on something else. I get a call in about 5 minutes saying that again, she can not connect. I look and the server is shutdown. I open up the log file this time to find out what she is doing that is making the server crash and I see that I have a “Stack Overflow” error. I started looking into this, since I am still pretty new to Sybase, and I see that I essentially have two options to resolve this problem. I can have the developers break the job into smaller SQL statements or I can change the Stack Size. So I started doing that by using ‘sp_configure “stack size”, new_value’. This is a static option and the server must be restarted after making the change. I added 50% more to the Stack Size and now the job is running as expected. Hope this can help someone that is having the same problem.


October 22, 2008  10:11 PM

Powershell Script to Monitor Disk Space

Colin Smith Colin Smith Profile: Colin Smith

So today I got alerted by one of my old VBScripts about a disk having less than 5 Gigs free. I had this script in place so that the SQL servers that I manage do not run out of space on the disk that the mdf and ldf files are on. When I logged into see what the problem was I noticed that on both servers the system drive was out of space. I went to the Windows team and let them know and they asked if I could put a script together to notify them if the situation happened again. So I thought I am sure I can and this time I am going to do it in Powershell and make the script better then my VBScript. I got a list of the servers that they wanted me to monitor for them and then I started scripting and here is what I did.

##########################################

###        Gather Disk Information     ###

##########################################

Clear-Content “D:\Scripts\Powershell\PAC\lowdisk.txt”

$i = 0

$users = “email@email.com”, ” email@email.com ”

$computers = Get-Content “D:\Scripts\Powershell\PAC\computerlistall.txt”

echo “ServerName        Drive Letter    Drive Size    Free Space    Percent Free” >> “D:\Scripts\Powershell\PAC\lowdisk.txt”

echo “———-        ————    ———-    ———-    ————” >> “D:\Scripts\Powershell\PAC\lowdisk.txt”

foreach ($computer in $computers)

{

    $drives = Get-WmiObject -ComputerName $computer Win32_LogicalDisk | Where-Object {$_.DriveType -eq 3}

    foreach($drive in $drives)

{

        $size1 = $drive.size / 1GB

        $size = “{0:N2}” -f $size1

        $free1 = $drive.freespace / 1GB

        $free = “{0:N2}” -f $free1

        $ID = $drive.DeviceID

        $a = $free1 / $size1 * 100

        $b = “{0:N2}” -f $a

##############################################

##    Determine if any disks low    ##

##############################################

        if (($ID -eq “D:”) -or ($ID -eq “S:”) -or ($ID -eq “T:”) -or ($ID -eq “C:”) -and ($free1 -lt 1))

        {

            echo “$computer        $ID            $size        $free        $b” >> “D:\Scripts\Powershell\PAC\lowdisk.txt”

            $i++

        }

    }

}

####################################################

##    Send Notification if alert $i is greater then 0         ##

####################################################

if ($i -gt 0)

{

    foreach ($user in $users)

{

        echo “Sending Email notification ro $user”

        $smtpServer = “smtp server”

        $smtp = New-Object Net.Mail.SmtpClient($smtpServer)

        $emailFrom = “fromuser@domain.com”

       $subject = “Email Subject”

        foreach ($line in Get-Content “D:\Scripts\Powershell\PAC\lowdisk.txt”)

{

            $body += “$line `n”

        }

        $smtp.Send($EmailFrom,$user,$subject,$body)

        $body = “”

    }

}

So if we break this down a bit here is essentially what I am doing. First I read in the servers to monitor from the file computerlistall.txt and then I give the scripts the names of the administrators that want to get the notifications. Then I set up my output file with some formatting. Now the good stuff, I make a WMI connection to the server and get a list of all the drives on the server. I then have to eliminate the CDROM and any other drive that is not actually a physical hard drive on the server. Then I get the disk size divide that by a gig and then I round that to two decimal places. Then I do the same for the free space. I am only rounding the disk free and size for the output. I am doing my conditional logic on the actual numbers to get the most accurate results possible. After I have all the variables then I do the conditional logic. I am saying that if it is any of the drive letters that I specified and the free space is less than 1Gig then output that to a file and increment my counter $i. So now I do a bit more logic and check the value of my counter. If $i is greater than 0 then I know that I have something that I need to send out a notification on. So I now send out the notifications as needed.

I set this up to run once a day but you can certainly do it more often. I set it up in the windows scheduler and it works just fine. Please let me know if you have any questions about this or need any help with it. You can also head over to my website at sysadminsmith.com to get help on pretty much anything.


October 22, 2008  4:25 PM

Why Powershell?

Colin Smith Colin Smith Profile: Colin Smith

In my first few posts here I have done a lot of things in Windows Powershell. Some of you may be asking why Powershell and I am busy asking why not Powershell. Since being introduced to Powershell any time I hear a request to do just about anything in Windows I think about how I can script that using Powershell. My team thinks that I should get compensation from Microsoft since I bring it up so much. We all laugh about it but I really think that if you want to continue to grow with Microsoft products then you need to learn Powershell.

If you do not already know, Powershell is Microsoft’s new Shell Scripting Language. It is object oriented and has a pipe. The pipe is a great tool that UNIX users have enjoyed forever and now we all get to enjoy the power of the pipe. Powershell is made up of commandlets. These are the commands that you will use to do things with objects. They use a standard verb-noun syntax so it is easy to understand. An example of one of the commandlets is as follows. This is a very useful command as it will tell you what other commands are available to you.


PowerShellPlus 1.0.4.7
(C) 2007-2008 Scriptinternals. All Rights Reserved.

PowerTab version 0.99 Beta 2 PowerShell TabExpansion library
/\/\o\/\/ 2007 http://thePowerShellGuy.com
PowerTab Tabexpansion additions enabled : True
PS C:\Documents and Settings\smithc> Get-Command

CommandType     Name                                                                  Definition
———–     —-                                                                  ———-
Cmdlet          Add-Content                                                           Add-Content [-Path] <String[]> [-Value] <Object[]> [-PassThru] [-…
Cmdlet          Add-History                                                           Add-History [[-InputObject] <PSObject[]>] [-Passthru] [-Verbose] …
Cmdlet          Add-Member                                                            Add-Member [-MemberType] <PSMemberTypes> [-Name] <String> [[-Valu…
Cmdlet          Add-PSSnapin                                                          Add-PSSnapin [-Name] <String[]> [-PassThru] [-Verbose] [-Debug] […
Cmdlet          Clear-Content                                                         Clear-Content [-Path] <String[]> [-Filter <String>] [-Include <St…
Cmdlet          Clear-Item                                                            Clear-Item [-Path] <String[]> [-Force] [-Filter <String>] [-Inclu…
Cmdlet          Clear-ItemProperty                                                    Clear-ItemProperty [-Path] <String[]> [-Name] <String> [-PassThru…
Cmdlet          Clear-Variable                                                        Clear-Variable [-Name] <String[]> [-Include <String[]>] [-Exclude…
Cmdlet          Compare-Object                                                        Compare-Object [-ReferenceObject] <PSObject[]> [-DifferenceObject…
Cmdlet          ConvertFrom-SecureString                                              ConvertFrom-SecureString [-SecureString] <SecureString> [[-Secure…
Cmdlet          Convert-Path                                                          Convert-Path [-Path] <String[]> [-Verbose] [-Debug] [-ErrorAction…
Cmdlet          ConvertTo-Html                                                        ConvertTo-Html [[-Property] <Object[]>] [-InputObject <PSObject>]…
Cmdlet          ConvertTo-SecureString                                                ConvertTo-SecureString [-String] <String> [[-SecureKey] <SecureSt…
Cmdlet          Copy-Item                                                             Copy-Item [-Path] <String[]> [[-Destination] <String>] [-Containe…
Cmdlet          Copy-ItemProperty                                                     Copy-ItemProperty [-Path] <String[]> [-Destination] <String> [-Na…
Cmdlet          Export-Alias                                                          Export-Alias [-Path] <String> [[-Name] <String[]>] [-PassThru] [-…
Cmdlet          Export-Clixml                                                         Export-Clixml [-Path] <String> [-Depth <Int32>] -InputObject <PSO…
Cmdlet          Export-Console                                                        Export-Console [[-Path] <String>] [-Force] [-NoClobber] [-Verbose…
Cmdlet          Export-Csv                                                            Export-Csv [-Path] <String> -InputObject <PSObject> [-Force] [-No…
Cmdlet          ForEach-Object                                                        ForEach-Object [-Process] <ScriptBlock[]> [-InputObject <PSObject…
Cmdlet          Format-Custom                                                         Format-Custom [[-Property] <Object[]>] [-Depth <Int32>] [-GroupBy…
Cmdlet          Format-List                                                           Format-List [[-Property] <Object[]>] [-GroupBy <Object>] [-View <…
Cmdlet          Format-Table                                                          Format-Table [[-Property] <Object[]>] [-AutoSize] [-HideTableHead…
Cmdlet          Format-Wide                                                           Format-Wide [[-Property] <Object>] [-AutoSize] [-Column <Int32>] …
Cmdlet          Get-Acl                                                               Get-Acl [[-Path] <String[]>] [-Audit] [-Filter <String>] [-Includ…
Cmdlet          Get-Alias                                                             Get-Alias [[-Name] <String[]>] [-Exclude <String[]>] [-Scope <Str…
Cmdlet          Get-AuthenticodeSignature                                             Get-AuthenticodeSignature [-FilePath] <String[]> [-Verbose] [-Deb…
Cmdlet          Get-ChildItem                                                         Get-ChildItem [[-Path] <String[]>] [[-Filter] <String>] [-Include…
Cmdlet          Get-Command                                                           Get-Command [[-ArgumentList] <Object[]>] [-Verb <String[]>] [-Nou…
Cmdlet          Get-Content                                                           Get-Content [-Path] <String[]> [-ReadCount <Int64>] [-TotalCount …
Cmdlet          Get-Credential                                                        Get-Credential [-Credential] <PSCredential> [-Verbose] [-Debug] […
Cmdlet          Get-Culture                                                           Get-Culture [-Verbose] [-Debug] [-ErrorAction <ActionPreference>]…
Cmdlet          Get-Date                                                              Get-Date [[-Date] <DateTime>] [-Year <Int32>] [-Month <Int32>] [-…
Cmdlet          Get-EventLog                                                          Get-EventLog [-LogName] <String> [-Newest <Int32>] [-Verbose] [-D…
Cmdlet          Get-ExecutionPolicy                                                   Get-ExecutionPolicy [-Verbose] [-Debug] [-ErrorAction <ActionPref…
Cmdlet          Get-Help                                                              Get-Help [[-Name] <String>] [-Category <String[]>] [-Component <S…
Cmdlet          Get-History                                                           Get-History [[-Id] <Int64[]>] [[-Count] <Int32>] [-Verbose] [-Deb…
Cmdlet          Get-Host                                                              Get-Host [-Verbose] [-Debug] [-ErrorAction <ActionPreference>] [-…
Cmdlet          Get-Item                                                              Get-Item [-Path] <String[]> [-Filter <String>] [-Include <String[…
Cmdlet          Get-ItemProperty                                                      Get-ItemProperty [-Path] <String[]> [[-Name] <String[]>] [-Filter…
Cmdlet          Get-Location                                                          Get-Location [-PSProvider <String[]>] [-PSDrive <String[]>] [-Ver…
Cmdlet          Get-Member                                                            Get-Member [[-Name] <String[]>] [-InputObject <PSObject>] [-Membe…
Cmdlet          Get-PfxCertificate                                                    Get-PfxCertificate [-FilePath] <String[]> [-Verbose] [-Debug] [-E…
Cmdlet          Get-Process                                                           Get-Process [[-Name] <String[]>] [-Verbose] [-Debug] [-ErrorActio…
Cmdlet          Get-PSDrive                                                           Get-PSDrive [[-Name] <String[]>] [-Scope <String>] [-PSProvider <…
Cmdlet          Get-PSProvider                                                        Get-PSProvider [[-PSProvider] <String[]>] [-Verbose] [-Debug] [-E…
Cmdlet          Get-PSSnapin                                                          Get-PSSnapin [[-Name] <String[]>] [-Registered] [-Verbose] [-Debu…
Cmdlet          Get-Service                                                           Get-Service [[-Name] <String[]>] [-Include <String[]>] [-Exclude …
Cmdlet          Get-TraceSource                                                       Get-TraceSource [[-Name] <String[]>] [-Verbose] [-Debug] [-ErrorA…
Cmdlet          Get-UICulture                                                         Get-UICulture [-Verbose] [-Debug] [-ErrorAction <ActionPreference…
Cmdlet          Get-Unique                                                            Get-Unique [-InputObject <PSObject>] [-AsString] [-Verbose] [-Deb…
Cmdlet          Get-Variable                                                          Get-Variable [[-Name] <String[]>] [-ValueOnly] [-Include <String[…
Cmdlet          Get-WmiObject                                                         Get-WmiObject [-Class] <String> [[-Property] <String[]>] [-Filter…
Cmdlet          Group-Object                                                          Group-Object [[-Property] <Object[]>] [-NoElement] [-InputObject …
Cmdlet          Import-Alias                                                          Import-Alias [-Path] <String> [-Scope <String>] [-PassThru] [-For…
Cmdlet          Import-Clixml                                                         Import-Clixml [-Path] <String[]> [-Verbose] [-Debug] [-ErrorActio…
Cmdlet          Import-Csv                                                            Import-Csv [-Path] <String[]> [-Verbose] [-Debug] [-ErrorAction <…
Cmdlet          Invoke-Expression                                                     Invoke-Expression [-Command] <String> [-Verbose] [-Debug] [-Error…
Cmdlet          Invoke-History                                                        Invoke-History [[-Id] <String>] [-Verbose] [-Debug] [-ErrorAction…
Cmdlet          Invoke-Item                                                           Invoke-Item [-Path] <String[]> [-Filter <String>] [-Include <Stri…
Cmdlet          Join-Path                                                             Join-Path [-Path] <String[]> [-ChildPath] <String> [-Resolve] [-C…
Cmdlet          Measure-Command                                                       Measure-Command [-Expression] <ScriptBlock> [-InputObject <PSObje…
Cmdlet          Measure-Object                                                        Measure-Object [[-Property] <String[]>] [-InputObject <PSObject>]…
Cmdlet          Move-Item                                                             Move-Item [-Path] <String[]> [[-Destination] <String>] [-Force] […
Cmdlet          Move-ItemProperty                                                     Move-ItemProperty [-Path] <String[]> [-Destination] <String> [-Na…
Cmdlet          New-Alias                                                             New-Alias [-Name] <String> [-Value] <String> [-Description <Strin…
Cmdlet          New-Item                                                              New-Item [-Path] <String[]> [-ItemType <String>] [-Value <Object>…
Cmdlet          New-ItemProperty                                                      New-ItemProperty [-Path] <String[]> [-Name] <String> [-PropertyTy…
Cmdlet          New-Object                                                            New-Object [-TypeName] <String> [[-ArgumentList] <Object[]>] [-Ve…
Cmdlet          New-PSDrive                                                           New-PSDrive [-Name] <String> [-PSProvider] <String> [-Root] <Stri…
Cmdlet          New-Service                                                           New-Service [-Name] <String> [-BinaryPathName] <String> [-Display…
Cmdlet          New-TimeSpan                                                          New-TimeSpan [[-Start] <DateTime>] [[-End] <DateTime>] [-Verbose]…
Cmdlet          New-Variable                                                          New-Variable [-Name] <String> [[-Value] <Object>] [-Description <…
Cmdlet          Out-Default                                                           Out-Default [-InputObject <PSObject>] [-Verbose] [-Debug] [-Error…
Cmdlet          Out-File                                                              Out-File [-FilePath] <String> [[-Encoding] <String>] [-Append] [-…
Cmdlet          Out-Host                                                              Out-Host [-Paging] [-InputObject <PSObject>] [-Verbose] [-Debug] …
Cmdlet          Out-Null                                                              Out-Null [-InputObject <PSObject>] [-Verbose] [-Debug] [-ErrorAct…
Cmdlet          Out-Printer                                                           Out-Printer [[-Name] <String>] [-InputObject <PSObject>] [-Verbos…
Cmdlet          Out-String                                                            Out-String [-Stream] [-Width <Int32>] [-InputObject <PSObject>] […
Cmdlet          Pop-Location                                                          Pop-Location [-PassThru] [-StackName <String>] [-Verbose] [-Debug…
Cmdlet          Push-Location                                                         Push-Location [[-Path] <String>] [-PassThru] [-StackName <String>…
Cmdlet          Read-Host                                                             Read-Host [[-Prompt] <Object>] [-AsSecureString] [-Verbose] [-Deb…
Cmdlet          Remove-Item                                                           Remove-Item [-Path] <String[]> [-Filter <String>] [-Include <Stri…
Cmdlet          Remove-ItemProperty                                                   Remove-ItemProperty [-Path] <String[]> [-Name] <String[]> [-Force…
Cmdlet          Remove-PSDrive                                                        Remove-PSDrive [-Name] <String[]> [-PSProvider <String[]>] [-Scop…
Cmdlet          Remove-PSSnapin                                                       Remove-PSSnapin [-Name] <String[]> [-PassThru] [-Verbose] [-Debug…
Cmdlet          Remove-Variable                                                       Remove-Variable [-Name] <String[]> [-Include <String[]>] [-Exclud…
Cmdlet          Rename-Item                                                           Rename-Item [-Path] <String> [-NewName] <String> [-Force] [-PassT…
Cmdlet          Rename-ItemProperty                                                   Rename-ItemProperty [-Path] <String> [-Name] <String> [-NewName] …
Cmdlet          Resolve-Path                                                          Resolve-Path [-Path] <String[]> [-Credential <PSCredential>] [-Ve…
Cmdlet          Restart-Service                                                       Restart-Service [-Name] <String[]> [-Force] [-PassThru] [-Include…
Cmdlet          Resume-Service                                                        Resume-Service [-Name] <String[]> [-PassThru] [-Include <String[]…
Cmdlet          Select-Object                                                         Select-Object [[-Property] <Object[]>] [-InputObject <PSObject>] …
Cmdlet          Select-String                                                         Select-String [-Pattern] <String[]> -InputObject <PSObject> [-Sim…
Cmdlet          Set-Acl                                                               Set-Acl [-Path] <String[]> [-AclObject] <ObjectSecurity> [-Passth…
Cmdlet          Set-Alias                                                             Set-Alias [-Name] <String> [-Value] <String> [-Description <Strin…
Cmdlet          Set-AuthenticodeSignature                                             Set-AuthenticodeSignature [-FilePath] <String[]> [-Certificate] <…
Cmdlet          Set-Content                                                           Set-Content [-Path] <String[]> [-Value] <Object[]> [-PassThru] [-…
Cmdlet          Set-Date                                                              Set-Date [-Date] <DateTime> [-DisplayHint <DisplayHintType>] [-Ve…
Cmdlet          Set-ExecutionPolicy                                                   Set-ExecutionPolicy [-ExecutionPolicy] <ExecutionPolicy> [-Verbos…
Cmdlet          Set-Item                                                              Set-Item [-Path] <String[]> [[-Value] <Object>] [-Force] [-PassTh…
Cmdlet          Set-ItemProperty                                                      Set-ItemProperty [-Path] <String[]> [-Name] <String> [-Value] <Ob…
Cmdlet          Set-Location                                                          Set-Location [[-Path] <String>] [-PassThru] [-Verbose] [-Debug] […
Cmdlet          Set-PSDebug                                                           Set-PSDebug [-Trace <Int32>] [-Step] [-Strict] [-Verbose] [-Debug…
Cmdlet          Set-Service                                                           Set-Service [-Name] <String> [-DisplayName <String>] [-Descriptio…
Cmdlet          Set-TraceSource                                                       Set-TraceSource [-Name] <String[]> [[-Option] <PSTraceSourceOptio…
Cmdlet          Set-Variable                                                          Set-Variable [-Name] <String[]> [[-Value] <Object>] [-Include <St…
Cmdlet          Sort-Object                                                           Sort-Object [[-Property] <Object[]>] [-Descending] [-Unique] [-In…
Cmdlet          Split-Path                                                            Split-Path [-Path] <String[]> [-LiteralPath <String[]>] [-Parent]…
Cmdlet          Start-Service                                                         Start-Service [-Name] <String[]> [-PassThru] [-Include <String[]>…
Cmdlet          Start-Sleep                                                           Start-Sleep [-Seconds] <Int32> [-Verbose] [-Debug] [-ErrorAction …
Cmdlet          Start-Transcript                                                      Start-Transcript [[-Path] <String>] [-Append] [-Force] [-NoClobbe…
Cmdlet          Stop-Process                                                          Stop-Process [-Id] <Int32[]> [-PassThru] [-Verbose] [-Debug] [-Er…
Cmdlet          Stop-Service                                                          Stop-Service [-Name] <String[]> [-Force] [-PassThru] [-Include <S…
Cmdlet          Stop-Transcript                                                       Stop-Transcript [-Verbose] [-Debug] [-ErrorAction <ActionPreferen…
Cmdlet          Suspend-Service                                                       Suspend-Service [-Name] <String[]> [-PassThru] [-Include <String[…
Cmdlet          Tee-Object                                                            Tee-Object [-FilePath] <String> [-InputObject <PSObject>] [-Verbo…
Cmdlet          Test-Path                                                             Test-Path [-Path] <String[]> [-Filter <String>] [-Include <String…
Cmdlet          Trace-Command                                                         Trace-Command [-Name] <String[]> [-Expression] <ScriptBlock> [[-O…
Cmdlet          Update-FormatData                                                     Update-FormatData [[-AppendPath] <String[]>] [-PrependPath <Strin…
Cmdlet          Update-TypeData                                                       Update-TypeData [[-AppendPath] <String[]>] [-PrependPath <String[…
Cmdlet          Where-Object                                                          Where-Object [-FilterScript] <ScriptBlock> [-InputObject <PSObjec…
Cmdlet          Write-Debug                                                           Write-Debug [-Message] <String> [-Verbose] [-Debug] [-ErrorAction…
Cmdlet          Write-Error                                                           Write-Error [-Message] <String> [-Category <ErrorCategory>] [-Err…
Cmdlet          Write-Host                                                            Write-Host [[-Object] <Object>] [-NoNewline] [-Separator <Object>…
Cmdlet          Write-Output                                                          Write-Output [-InputObject] <PSObject[]> [-Verbose] [-Debug] [-Er…
Cmdlet          Write-Progress                                                        Write-Progress [-Activity] <String> [-Status] <String> [[-Id] <In…
Cmdlet          Write-Verbose                                                         Write-Verbose [-Message] <String> [-Verbose] [-Debug] [-ErrorActi…
Cmdlet          Write-Warning                                                         Write-Warning [-Message] <String> [-Verbose] [-Debug] [-ErrorActi…

PS C:\Documents and Settings\smithc>


As you can see you have a lot of tools already built in after you install Powershell. Powershell is available from Microsoft as KB926139. I recommend going out and getting it and start learning how to use it.

Microsoft already has Powershell support built in to Exchange 2007, and SQL Server 2008. With Powershell you, as an administrator, can do more things using Powershell than you can with the GUI. Who would have ever thought that Microsoft would allow us to use a command line tool so efficiently? Since Microsoft has done this with these products I am sure that they will be continuing down this path. In fact with Server 2008 they have a core version that does not even have a GUI. I love it. Finally a light weight and very powerful OS and a great scripting tool to go along with it. In the future I expect to see more development of Powershell, version 2.0 is on the way, from Microsoft as well as third parties in order to get it to interface with other applications. Please take some time to explore and learn more about this great tool and I will have more on this topic in the future.

Thanks for reading this and I hope you learned something and I hope you are excited about Powershell like I am. Let me know if you have any questions by leaving a comment or go to sysadminsmith.com to drop me an email.


Forgot Password

No problem! Submit your e-mail address below. We'll send you an e-mail containing your password.

Your password has been sent to: