Educating the world

Our blog has over 10,000 readers a month

Zen Internet's customer portal

June 21st, 2011

For a company with such a good track record for customer support their online customer portal leaves a lot to be desired.

These are a couple of the things I need to do every now and again, but I just seem to spend ages hunting around for the options. The site is really slow and uses some sort of awful home grown Javascript front end that means you can’t open more than one window at a time otherwise the site won’t work as expected.

Show outstanding invoices:
Click My Billing
In the Quick links section click View your site’s current billing

Scripting with Windows PowerShell Part 3

June 16th, 2011

Working with Windows Management Instrumentation (WMI) information to retrieve essential information
Part 3 of a 5 part series.

Event logs

These commands will work on the local machine or a machine across the network. Most of the EventLog commands accept Computer name as an option, but do not accept any credentials. So connections made to a another machine must be able to impersonate you. If the security hasn’t been set up that way then you must use a different method such as the PowerShell Remoting commands (Invoke-Command), WMI (with Get-WmiObject) or Enter-PSSession.

Get-EventLog -List

Lists all the classic event logs. Classic seems to refer to the log names that were around years ago in NT3/NT4 days, but this list contains classic and new logs. So Ed Wilson, we’re just refer to this list of logs as a list of logs - ya’know to avoid any confusion!

Max(K) Retain OverflowAction        Entries Log
------ ------ --------------        ------- ---
   512      7 OverwriteOlder            724 ACEEventLog
20,480      0 OverwriteAsNeeded       4,146 Application
20,480      0 OverwriteAsNeeded           0 HardwareEvents
   512      7 OverwriteOlder              0 Internet Explorer
20,480      0 OverwriteAsNeeded           0 Key Management Service
 8,192      0 OverwriteAsNeeded           0 Media Center
   128      0 OverwriteAsNeeded          11 OAlerts
20,480      0 OverwriteAsNeeded       4,621 Security
20,480      0 OverwriteAsNeeded       7,618 System
15,360      0 OverwriteAsNeeded         231 Windows PowerShell

The “Windows PowerShell” (above) log is pretty useless and will probably just have a load of messages saying “powershell started". We can read a log by using its log name on the command line:

Get-EventLog -LogName application -Newest 5

Index Time          EntryType   Source                 InstanceID Message
----- ----          ---------   ------                 ---------- -------
 4146 Jun 03 16:23  Information Office Software P...   1073742827 The Software Protection service has completed
 4145 Jun 03 12:06  Information McLogEvent             1073746824 McShield service started....
 4144 Jun 03 11:05  Information Windows Error Rep...         1001 Fault bucket , type 0...
 4143 Jun 03 11:05  Information McLogEvent             1073742081 The scan of D:\DOWNLO~1\ECLIPS~2.ZIP has taken
 4142 Jun 03 11:05  Information McLogEvent             1073742081 The scan of D:\DOWNLO~1\ECLIPS~1.ZIP has taken

Each one of the entries has 6 columns, but as we know from previous lessons these 6 columns are just a cut down version of what is available. To see more we’ll use the Format-List to show them all:

Get-EventLog -LogName application -Newest 1 | Format-List *

EventID            : 1003
MachineName        :
Data               : {}
Index              : 4146
Category           : (0)
CategoryNumber     : 0
EntryType          : Information
Message            : The Software Protection service has completed licensing status check.
                     Application Id=59a52881-a989-479d-af46-f275c6370663
InstanceId         : 1073742827
TimeGenerated      : 03/06/2011 16:23:19
TimeWritten        : 03/06/2011 16:23:19
UserName           :
Site               :
Container          :

It might be nice to see on what other occasions The Software Protection service ran.

Get-EventLog -LogName application | Where { $_.message -match ‘protection’ }

The -match takes a regular expressions so in our case it is looking for the word “protection” anywhere on the line. The results come back and you may have to take advantage of the control+c keyboard sequence to stop the current command.

Index Time          EntryType   Source                 InstanceID Message
----- ----          ---------   ------                 ---------- -------
 4146 Jun 03 16:23  Information Office Software P...   1073742827 The Software Protection service has comple
 4116 May 31 14:28  Information Office Software P...   1073742827 The Software Protection service has comple
 4115 May 31 14:28  0           Office Software P...   1073742726 The Software Protection service has starte
 4114 May 31 14:28  Information Office Software P...   1073742890 Initialization status for service objects.
 4113 May 31 14:28  Information Office Software P...   1073742724 The Software Protection service is startin

Ed tried to make excuses for the slowness of his results being displayed. “But that’s cool because we’re filtering out through a whole lot of entries, then doing a match of the message, and it’s like having to read all the messages and look for that sequence of characters.” - Really? I mean you would expect a little delay between the results being displayed, but not that much. It looks to me like he hadn’t installed the graphics card on his PC properly and the scroll rate had dropped through the floor - that old chestnut &#59;) Anyway I tried it and it was fine. With event logs we can filter on InstanceID by adding the -InstanceId switch.

Get-EventLog -LogName application -InstanceId 1073742827

While the results are equivalent to a statement containing a Where-Object cmdlet, it is much quicker because the instance filtering is done inside the Get-EventLog cmdlet i.e. the non-matching InstanceId records never have to travel down the pipe. Wow, that’s another 5 minutes I’ll never get back.

Get-EventLog -LogName application |where {$_.InstanceId -eq 1073742827}

Let’s say we want to filter on Source. We can’t see all of the Source name so we can expand that column using the Select-Object cmdlet (Select is an alias for Select-Object):

Get-EventLog -LogName application -InstanceId 1073742827 -Newest 5 | select source

Software Protection Platform Service
Windows Search Service
Office Software Protection Platform Service
Office Software Protection Platform Service
Software Protection Platform Service

All values of the source column have been fully expanded. For the purpose of expanding column names we could have just used one of the format cmdlets (Format-Table / Format-List). Select-Object is supposed to manipulate lists of objects such as finding unique entries or returning a sub-list. So to finish the previous example, we can specify the full source name or we can use a wild card:

Get-EventLog -LogName application -Source “Software Protection Platform Service” Get-EventLog -LogName application -Source “Software Protec*”

In the past Ed’s “always hated typing dates, erm… simply for the fact, y’know, you never really know exactly how these things are going to be interpreted, and all of that", but not with PowerShell because there are filter switches of -Before and -After. Perhaps he should revisit the other search applications and read the instructions! The -Before and -After switches expect dates so the format is pretty flexible and is based on your locale or as they call it Culture. To find out which Culture you are in, issue the command:


LCID             Name             DisplayName
----             ----             -----------
2057             en-GB            English (United Kingdom)

Getting back to our date filtering example. An interesting shortcut is that -A is short for -After, -B is short for -Before and as it turns out you can shorten a switch to it’s minimum unique name. For example on Get-EventLog the shortest switch for -LogName is -LogN because if you tried -Log it would interfere with -Log which has a different function.

Get-EventLog -LogName application -After 01-06-2011 -Before 02-06-2011
Get-EventLog -LogName application -A “1 June 11″ -B “2 Jun 2011″
Get-EventLog -LogName application -Aft “1 - 06 - 11″ -Bef “2 / 6 / 2011″

Event Trace Logs (ETL)

Event Trace Logs (ETL) is EventLog version 2. There are a different set of cmdlet tools to hope with the new format of the logs and the additional data held in those logs. The new version is backward compatible with the old classic style of logging, so you could avoid using Get-EventLog in favour of Get-WinEvent. ETL was introduced in Vista and is available in operating systems after that. Load the Event Viewer using Start -> Control Panel -> Administration -> Windows Event Viewer. Under Windows Logs there are the classic logs, under that is the Application and Service Logs are more of the logs that are available with the Get-EventLog cmdlet, but are some how not classic.

We are going to be looking at the Trace and Debug logs. The first got-cha is that these logs don’t show up by default, you have to explicitly switch them on. From the Event Viewer panel highlight Application and Service Logs and file menu make sure that View -> Show Analytic and Debug Logs is checked. Application and Service looks like a place to contain logs from other companies. These new logs (or style of logs) split the data into different categories like Operation, Verbose, Analytic, etc. Operational logs seem to be switched on by default where as Trace, Diagnostic and others seem to be switched off by default. As you can see there are literally hundreds of log files available, so you can find information on almost any kind of issue that the system might be going through.

We are going to be looking at WMI activity so scroll down to WMI-Activity. When we click on the log icon (in the panel view) we get a list of the current log entries. Trace logs are switched off so we must enable it explicitly. Right-click on the log icon and select Enable Log. There is a scary warning about losing log entries when this is enabled so in Ed’s words: “it’s gonna whine, and I say yeh, yeh, yeh, so this is cool". When the scary message says “lose events” I think it means lose them from the view as opposed to them disappearing down a black hole. It would have been another: “Thanks Bill” for creating a logging system that is either disabled or almost-enabled! So let’s now list those logs via PowerShell.

The first thing to deal with is the got-cha I mentioned above. Just like the trace and diagnostic logs needed explicitly enabling in the Event Viewer; they need explicitly switching on in the PowerShell too. This is achieved with the -Force switch. The -Force switch works in combination with the -LogName switch. If you specify the -LogName name (in full) then Get-WinEvent will allow you access to that one log. If you use a wildcard in the -LogName only the Operational level log files will be used in the search space to find a match. If you use a wildcard in the -LogName and -Force then the log files, including all the Trace and Diagnostic logs, will be used in the search. The following 3 examples will help show the effects of this. Some of the entries may be blank because you don’t have the right privileges to see them. I have expanded the -LogName so that you can see the difference but when you do it they may be truncated, so don’t forget you can use Select-Object to only display the columns you want.

Get-WinEvent -ListLog “*CodeIntegrity*”

LogName                                 MaximumSizeInBytes    RecordCount  LogMode
-------                                 ------------------    -----------  -------
Microsoft-Windows-CodeIntegrity/Operational  1052672              4       Circular

Get-WinEvent -ListLog “*CodeIntegrity*” -Force

LogName                                 MaximumSizeInBytes    RecordCount  LogMode
-------                                 ------------------    -----------  -------
Microsoft-Windows-CodeIntegrity/Operational 1052672               4            Circular
Microsoft-Windows-CodeIntegrity/Verbose     1052672                            Retain

Get-WinEvent -ListLog “Microsoft-Windows-CodeIntegrity/Verbose”

LogName                                  RecordCount
-------                                  -----------
Microsoft-Windows-CodeIntegrity/Verbose  1052672

A bit of advice from Ed:

  1. “‘Use the Force Luke’, even if you’re name isn’t Luke you can still use the Force”
  2. “You’ll need to use the Force parameter only often enough, that when you do need to use it, you’ll probably forget about it, well at least that’s my behaviour anyway.”
  3. “You’ll have to actively train yourself to try and add this Force parameter, now if this is something you really don’t like, then you can actually write a function that wraps this cmdlet and automatically adds the Force to it, so that you don’t have to add it.”

The first bit of advice is obviously silly, bizarrely he kept saying “Use the force” like it was some kind of trigger but there’s no memory trigger for me that links make-my-command-work and Star Wars. The second bit of advice shows he is silly and the third bit of advice shows he gives silly advice.

The cmdlet Get-WinEvent has 2 roles: list the available logs (ListLog) and list the contents of a particular log (LogName). In almost the same way that you had to include -Force to make ListLog work you must use -Oldest to make -LogName work. Great, switches that don’t have to be specified but if you don’t use them, then it won’t work!

This particular log file is stored in chronological order which has oldest first. The default is newest first which is why it barfs when you don’t specify the -Oldest option to reverse the retrieval ordering. These log names increase the size of the command line so that it wraps. So now is probably a good time to see the PowerShell ISE - because it can wrap lines!

PowerShell ISE can be found in: Start Menu -> Programs -> Accessories -> Windows PowerShell ISE. After loading it in you will see 3 main areas: top, middle and bottom. The top section can hold a PowerShell script and run it line by line. The middle is all the output. The bottom section is almost the same as the regular PowerShell window in that you use the up and down arrows to go through your history. It looks like you practice writing PowerShell in the bottom panel, when you have got your command correct you can copy it to the script panel at the top. Do this for each line until you have a complete script which can be saved. Place the caret in the top panel at the line you would like to start running from and press the button with the green triangle (or F5) to start running. Each line will be echo’ed in the middle panel and if there are any errors, they will be displayed in red under the command. You can practice by entering one of the following lines into the bottom panel and hitting return. All the lines are equivalent. If we remember back to our magic parameters, in this case the magic parameter is Class i.e. if we add a command argument with no switch then this is the default switch to use.

Get-WmiObject -Class win32_bios
gwmi -Class win32_bios gwmi win32_bios

To give yourself something to look at in the PowerShell ISE enter the following command in to the top script panel and run it:

Get-WinEvent -LogName Microsoft-Windows-WMI-Activity/Trace -Oldest | where { $_.message -match ‘Class’ } | select message -ExpandProperty message

Don’t worry if the PowerShell ISE introduction didn’t make any sense, because it didn’t to me either! PowerShell ISE is better then the blue command box because it is more colourful and it allows you to save the command text separately. Other than that, PowerShell ISE is a pretty poor attempt at a integrated development environment. Ed Wilson is the Microsoft man for PowerShell and runs the HeyScriptingGuy blog site on Technet. He has a page devoted to logs and monitoring:

You can save an event log then you can use Get-WinEvent to parse that saved log. You can store all your event logs in a single location, use Get-ChildItem to do a directory listing of that location, open up all the files and look for a specific event. You might use this to correlate events for forensic analysis, where something has happened and you have to track it’s course through the system. Ed then takes us on a rough guide of his blog, and it looks pretty. He mentions a profiling cmdlet called Measure-Command that is used to measure the performance of different commands in order to optimise different solutions.

Questions and answers

Q: Are there tools to convert Korn shell scripts to PowerShell scripts?
A: No - not recommended because a Korn shell will be heavy on regular expressions for parsing text whereas PowerShell returns objects.

Q: Can I reboot a remote server with PowerShell?
A: Yes. There is a Stop-Computer and Restart-Computer cmdlet, so as long as you have connectivity and rights then you should be good. These commands take a list of computer names to use so you could reboot a list of computers.

Q: What is the difference between a single quote and a double quote?
A: A single quote(’) is a literal string and a double quote(") is an expanding string. The back-quote character (`) delimits the dollar and turns it into a normal character. Back-quote does the work of the back-slash in every other language I’ve come across.

echo ‘a=$a’
echo “a=$a”
echo “a=`$a”
echo “number ‘$a’ is lucky for some”
number ‘13′ is lucky for some

Q: How can I sort a column after selecting?
A: Pipe it to the Sort-Object cmdlet specifying the column you wish to sort on. You can use the -Descending to change the order.

Get-Process | Sort-Object processname

Q: Can you cache the event log in memory before filtering, would that be faster?
A: You could read the entire event log into a variable and then you could do stuff. If you have lots of parsing and filtering then it could be faster. If you don’t have much to do then it’s much faster to do the filtering on the computer where the log sits.

Q: Can I do everything with events viewer using the PowerShell cmdlet?
A: Yes, if he was talking about doing everything in computer management then No.

Q: Can you use the up arrow to bring up a multi-line command statement in one?
A: No.

Q: Can you use PowerShell to monitor events as they occur?
A: Yes, there’s a whole series of articles on the HeyScriptingGuy site, mumble, mumble, mumble, look for the tag events, use can use WMI events or Windows events. [He just mumbled through the answer without saying anything coherent].

Q: Have you used Enter-PSSession and it’s related cmdlets?
A: Of course, I have. Search the HeyScriptingGuy site with the tag of Remoting.

Q: What is the difference between smooth brackets “()” and curly brackets “{}"?
A: Smooth brackets are used as parameters coming into methods opener and closers whereas curly brackets are typically used for script blocks or code blocks. I can use “@(” to create an array and “@{” to create a hashtable.

PowerShell array creation

$b = @("1″, “2″, “32″, “4″)


PowerShell hashtable creation

$m = @{"a” = “1″} + @{"b"="2″}

Name  Value
----  -----
a     1
b     2

PowerShell subexpressions

$x = 10
echo $($x * 10)

Scripting with Windows PowerShell Part 2

June 3rd, 2011

Sorting, grouping, and formatting output
Part 2 of a 5 part series.

There is no difference between running PowerShell commands on the command line or running them in a script, so it’s more like a Unix shell. PowerShell cmdlets have a 2 part name: a verb followed by a noun. For example, Get-Process, Get-Service, Get-EventLog, Set-Service, Start-Process, Add-Content. We can get a list of all the verbs using:


Verb    Group
----    -----
Add     Common
Clear   Common
New     Common
Wait    Lifecycle
Debug   Diagnostic

If you stick to these “approved” verbs, it will make it easier for you to find (or guess) the command you are looking for. Let’s say we want to create a new file. We can see there is a New verb and so we can use the Get-Command command to find other commands that start with the New command verb.

Get-Command -Verb new

CommandType Name          Definition
----------- ----          ----------
Cmdlet      New-Alias     New-Alias [-Name] <String> [-Value] <String> [-D...
Cmdlet      New-Event     New-Event [-SourceIdentifier] <String> [[-Sender...
Cmdlet      New-EventLog  New-EventLog [-LogName] <String> [-Source] <Stri...

We can see that we can use Windows PowerShell to create a new event log and new events. We can have our own personal event log or an event log shared by all our scripts.

The last article Scripting with Windows PowerShell Part 1 looked at the Get-Process command that lists some common attributes of a running process, however the list of columns is cut down. There is loads more information available from the command. We can use Format-List to retrieve it.
Launch notepad so we have something to play with. Do a Get-Process notep* so we can find it’s PID in case we have more than one notepad loaded.

Get-Process -id 4180 | Format-List *

__NounName   : Process
Name         : Notepad2
Handles      : 69
VM           : 77967360
WS           : 7745536
PM           : 1986560
NPM          : 7680
Path         : C:\Program Files\Notepad2\Notepad2.exe
NonpagedSystemMemorySize   : 7680
NonpagedSystemMemorySize64 : 7680
PagedMemorySize64          : 1986560
PagedSystemMemorySize      : 159088
StartTime                  : 18/05/2011 17:27:27

We can use the -Property to just display the one we want.

Get-Process -id 4180 | Format-List -Property StartTime

StartTime : 18/05/2011 17:27:27

We can display the results in a table, so let’s create a table containing the process name and the start time of each process. In the example I use “name", but “name” is an alias for “processname".

Get-Process | Format-Table -Property name,starttime

Name         StartTime
----         ---------
albd_server  17/05/2011 09:34:45
atieclxx     17/05/2011 09:35:04
atiesrxx     17/05/2011 09:34:40
CCC          17/05/2011 09:36:12
cccredmgr    17/05/2011 09:34:45

You can see that audiodg doesn’t have an associated StartTime. This is because my current user doesn’t have enough privileges to see it. We can re-run the command as a privileged user or we can filter out the entries where StartTime is blank. You should be getting the hang of this now. The Scripting Guy (Ed Wilson) gave a couple of waffley excuses why the where couldn’t go at the end. The long and the short of it is that once text/records/objects have flowed through a pipe into a formatter they no longer have their object association and are in fact just text (like in a traditional unix pipe). To that end the where must go before any formatting has corrupted the data. Another change is that we will be treating the records created by the Get-Process as real objects and so we need the where-object condition statement instead of a normal where.

Get-Process | where-object { $_.starttime } | Format-Table -Property name, starttime

This is a lot of typing but there are aliases for most of the commands

gps | ? { $_.starttime } | ft name, starttime

gps = (alias for) Get-Process
? = where ("where” is an alias of Where-Object)
ft = Format-Table (and it knows that -Property is the magic attribute in the same way that -id is the magic attribute for Get-Process).

It is recommended not to use aliases inside your scripts. All scripts should be readable and transferable which might not be the case if they are full of aliases.

You can find out about aliases with:


If you enter a command which is syntactically incorrect then you will get an error message describing the problem in English! Enter the broken command:

Get-Alias where-object

Get-Alias : This command cannot find a matching alias because alias with name 'where-object' do not exist.
At line:1 char:10
+ Get-Alias <<<<  where -object
    + CategoryInfo          : ObjectNotFound: (where-object:String) [Get-Alias], ItemNotFoundException
    + FullyQualifiedErrorId : ItemNotFoundException,Microsoft.PowerShell.Commands.GetAliasCommand

From the error message we can see that the ‘where-object’ is not a valid alias. Wow, I think we have reached a new heights of waffle. It took slightly over a minute to say “read any error messages, because they will help you"!

Ed spent a minute or two trying to show that ? was an alias for where, but failed because ? is a wildcard character meaning “a single character". Try it:

Get-Alias ?

CommandType  Name Definition
-----------  ---- ----------
Alias        %    ForEach-Object
Alias        ?    Where-Object
Alias        h    Get-History
Alias        r    Invoke-History

He (Ed) then tried Get-Alias -Name ? and Get-Alias -Name “?” to no avail. I tried a couple of other solutions to try and delimit the wildcard property of the question mark, but I couldn’t either. During the questions and answers at the end of the webcast a live listener offered the answer, which flies in the face of everything we know about command line parsing. Trust Microsoft to get themselves in a pickle then invent a way of getting out of it by destroying something else. Anyway here’s the answer:

get-alias -name [?]

Eventually he showed us the less useful reciprocal command to find the aliases for a particular command:

Get-Alias -Definition where-object

CommandType Name  Definition
----------- ----  ----------
Alias       ?     Where-Object
Alias       where Where-Object

From Scripting with Windows PowerShell Part 1 we re-cap:

get-service | Where-Object { $_.status -eq “running” }

Status   Name               DisplayName
------   ----               -----------
Running  Albd               Atria Location Broker
Running  AMD External Ev... AMD External Events Utility

We use the heading name as the identifier in the $_ line object. It would appear that the normal output you get from Get-Services isn’t the only information, like Get-Process there seems to be a lot of “hidden” information that is available.

Let’s say we wish to find all the services that we can pause? We can use the Format-List (with the show-everything wild-card star) to find out about the hidden columns. You can add a “| more” to stop it scrolling off the top of the screen if you like or press CONTROL+c, to cancel the scrolling before the end.

Get-Service | Where-Object { $_.status -eq “running” } | Format-List *

Name                : Albd
RequiredServices    : {TcpIp, RpcSs}
CanPauseAndContinue : True
CanShutdown         : False
CanStop             : True
DisplayName         : Atria Location Broker
DependentServices   : {}
MachineName         : .
ServiceName         : Albd
ServicesDependedOn  : {TcpIp, RpcSs}
ServiceHandle       : SafeServiceHandle
Status              : Running
ServiceType         : Win32OwnProcess
Site                :
Container           :

Name                : AMD External Events Utility

Here we can see the list of all the available attributes. We can then inspect the list and examine each CanPauseAndContinue to see which is set to true. To speed things up we can use CanPauseAndContinue as our $_ filter. Truth is implied by virtue of the fact that it is set to something (i.e. not empty):

Get-Service | Where-Object { $_.CanPauseAndContinue }

Status   Name          DisplayName
------   ----          -----------
Running  Albd          Atria Location Broker
Running  cccredmgr     Rational Cred Manager
Running  LanmanServer  Server

Applying a filter is much better than visually inspecting the results by hand - thanks Ed that’s another minute of life I will never get back. We could have used Get-Member to help us select an appropriate property to filter on. (Don’t worry, we’ll look at Get-Member a bit later on).

Pausing LanmanServer will prevent anyone from making new connections to the machine, but how to we pause a service? Let’s take a look at our service commands. I had a quick guess about how to do this. First, I did:

Get-Command -Name *service*

CommandType  Name                                Definition
-----------  ----                                ----------
Application  api-ms-win-service-core-l1-1-0.dll  C:\Windows
Application  CcVsiLanService.dll                 C:\Program
Cmdlet       Get-Service                         Get-Servic

which contained all sorts of other things so then I did a:

Get-Command -Name *service* | Where-Object { $_.commandType -eq “cmdlet” }

CommandType Name                 Definition
----------- ----                 ----------
Cmdlet      Get-Service          Get-Service [[-Name] <st
Cmdlet      New-Service          New-Service [-Name] <Str
Cmdlet      New-WebServiceProxy  New-WebServiceProxy [-Ur
Cmdlet      Restart-Service      Restart-Service [-Name]
Cmdlet      Resume-Service       Resume-Service [-Name] <
Cmdlet      Set-Service          Set-Service [-Name] <Str
Cmdlet      Start-Service        Start-Service [-Name] <S
Cmdlet      Stop-Service         Stop-Service [-Name] <St
Cmdlet      Suspend-Service      Suspend-Service [-Name]

which yielded the correct results. I failed to realise the Service is the Noun component of the PowerShell cmdlet and what I should have done was a

Get-Command -Noun *service*

As you can see there are several things that might fit: Resume-Service and Suspend-Service but Ed shows us Set-Service instead because you can do it all in one command. It would seem that Resume-Service and Suspend-Service are short-cuts for Set-Service -Status enabled and Set-Service -Status disabled respectively.

Set-Service -Name lanmanserver -Status paused
Get-Service -Name lanmanserver

Status  Name           DisplayName
------  ----           -----------
Paused  lanmanserver   Server

Set-Service -Name lanmanserver -Status running will resume the service.
If it moans about “Access denied” then you will have to run the PowerShell as an administrator.

We can use Get-Member to discover what properties and methods we can use on a particular cmdlet.

Get-Service | Get-Member

   TypeName: System.ServiceProcess.ServiceController

Name                MemberType    Definition
----                ----------    ----------
Name                AliasProperty Name = ServiceName
RequiredServices    AliasProperty RequiredServices = ServicesDependedOn
Disposed            Event         System.EventHandler Disposed(System.Object, System.Event
Close               Method        System.Void Close()
WaitForStatus       Method        System.Void WaitForStatus(System.ServiceProcess.ServiceC
CanPauseAndContinue Property      System.Boolean CanPauseAndContinue {get;}
CanShutdown         Property      System.Boolean CanShutdown {get;}

We can see methods that we can run on a service. WaitForStatus looks like an interesting Method. This is similar to the Window’s Management Interface (WMI).

Get-WmiObject win32_service

ExitCode  : 0
Name      : AeLookupSvc
ProcessId : 0
StartMode : Manual
State     : Stopped
Status    : OK

ExitCode  : 0

If we pipe the output of the Get-WmiObject into Format-List or Get-Member we can see more detailed information and available options.

Get-WmiObject win32_service | Format-List *
Get-WmiObject win32_service | Get-Member

Where Format-List will give us a list of properties and values there as Get-Member will us the prototypes and method signatures. Try them!
If we wanted to set the password for a service we would have to use WMI commands instead because Set-Service doesn’t support it.

We can start programs on the command line just by running the program, but Start-Process gives us a little more control over the way in which the process starts. By typing Get-Help Start-Process we can find out that we can launch the application from a particular location, re-direct output, set the working directory, up environment variables or starting an application minimized:

Start-Process -WindowStyle Minimized -FilePath notepad

In the case of Start-Process the -FilePath is the magic command line switch so that the following commands are equivalent:

Start-Process -FilePath notepad
Start-Process notepad

We have specified Minimized as the WindowStyle but if we get it wrong the error message will specify the possible enumerations for that command line option.

Strangely Start-Process | Get-Member doesn’t produce any results because Start-Process has required fields.

Questions and answers
Q: Is there a way to start PowerShell from the run dialogue box?
A: Yes, Start -> Run, then type powershell.

You can get the help from a command prompt by:

powershell -?

PowerShell[.exe] [-PSConsoleFile  | -Version ]
    [-NoLogo] [-NoExit] [-Sta] [-NoProfile] [-NonInteractive]
    [-InputFormat {Text | XML}] [-OutputFormat {Text | XML}]

NoExit = will leave it running.
Sta = Start the shell using single-threaded apartment mode.
NoProfile = starts the script without running you profile. Good for testing because the destination machine won’t have the same profile as you.
EncodedCommand = if characters on the command line are too complicated then you can accept them base-64 encoded.
Command = you can either pass in a command, a script block or a script file.
For more information you can read the rest of the help.

Here are some examples of running powershell from the start menu or as part of a scheduled task:
powershell same as powershell -noexit
Runs up a powershell that stays open.

powershell Get-Process
Runs the Get-Process command then exits

powershell -noexit Get-Process
Runs the Get-Process command then gives you the command line.

powershell &{get-process; sleep 2}
Run powershell using an in-line script block that lists the processes, waits for 2 seconds then exits.

powershell -file c:\file.ps1
Runs the file.ps1 script. ps1 is the given extension of powershell scripts.

Q: Is there any difference between running an executable from the command line or via PowerShell’s Start-Process
A: No.

Another useful alias is sort which is an alias for Sort-Object. A nice example of this is:

Get-Process | Sort-Object handles

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
      0       0        0         24     0               0 Idle
     30       2      448       1152     5     0.05    272 smss
     31       4      872       2568    22     0.00   2056 conhost
     55       6     1148      20752    26     0.02   1396 svchost
     58       7     1176      20756    26     0.02   1152 svchost

Remember you can use Help -Full sort to get a set of examples.

Q: Can I use and equals sign “=” instead of -eq in the where clauses?
A: No, equals is used as an assignment operator.

PS C:\> $d = 40
PS C:\> $d
PS C:\\>

Q: How do I start or stop a process on a remote computer?
A: Start-Process/Stop-Process only work on the local computer. You would have to use WMI or the newer PowerShell invoke-command (PowerShell v2+).

Invoke-Command -ComputerName my-host -ScriptBlock {Start-Process notepad} -Credential my-user\my-domain

Q: Do you have to install PowerShell on both machines.
A: Yes, unless you are talking over WMI.

Q: Could you show how to use Get-Process to sort the startup time?
A: Ed never answered this but here you go!

get-process | Sort-Object $_.starttime | Format-List name, starttime

Q: Can I use powershell -ExecutionPolicy to override the default policy and allow unsigned scripts to run when unsigned scripts are by default prohibited?
A: Yes you can, use -ExecutionPolicy bypass

Q: How do you run a command against another server with altered credentials?
A: Basically any command that has the -Credential option will let you do it.

Q: Can you use ADSI to stop remote services?
A: Yes

Q: Is there a way to encrypt the password so you do not have the privileged account in plain text?
A: Yes, you can create a Credential object and use that instead.

Q: Does the Invoke-Command require powershell v2
A: Yes.

Q: Can you change how much history you store?
A: Yes, change the variable $MaximumHistoryCount to number of entries:

$MaximumHistoryCount = 128

Channel 4's Campus - Analysis of Men and Women

June 2nd, 2011

Flatpack has fallen in love with Imogen Moffat, and he goes to see the English professor Matt Beer in order to get some hints on how to woo her.

Matt Beer:

Think surf and turf.

Women are the sea, the surf. Their minds are always shifting, their bodies, like the tide, are ruled by the pull of the moon. Women have hidden depths where dark and dangerous things lurk, but in their shallows, you’ll be safe. Never go in deeper than your knees, but if you want more, you have to be prepared to venture out of your depth, where in all likelihood you will get sucked down by a vicious undercurrent and swept out into the endless black ocean of the female psyche where, sadly, you will drown.

Men are the turf. Thick, solid sods of earth that get under your nails. What you see is what you get.

You have been paddling too long. You must put on your water wings and explore her hidden depths.

Future learning bookmarks

May 20th, 2011

You know how you see an article and you think “ooh I’d love to play with that"? Well that’s what this article is about! The tutorial section contains links to comprehensive step-by-step walk throughs of setting up and getting started with a particular language or technology. The second section is for starting point links and investigations. So if I want to keep a link while I’m looking for the uba tutorial that’s where it will live.

Tutorials - get yourself going

Facebook Apps

Learning Android


Put up a REST API for Xbox Gamertag Data


Support and Teaching
Screen recorder: CamStudio:

GoTo Assist (Support)

Starting points and investigation

Java and Speech

Handy one-liners for SED

Face to face
Reading Geek Night (UK)