Feeds:
Posts
Comments

Archive for February, 2010

Blog is moving! You should check this post out on kevinpelgrims.com

What is this PowerShell script for?

On my last project I had a few problems with a Sharepoint service on a server, we couldn’t find the problem straightaway, but restarting the service always seemed to help for a while. Connecting to the server with Remote Desktop and restarting the service, however, is pretty timeconsuming for such a simple task, so I made a little PowerShell script to restart the service remotely.

A screenshot with the script in action (click it for a better look):

Show me the script!

So, how do I start to write this script? As a PowerShell beginner I Google a bit, and stumle upon this nice post on The PowerShell Guy blog.

[System.ServiceProcess.ServiceController]::GetServices('server')

(new-Object System.ServiceProcess.ServiceController('Service','server')).Start()
(new-Object System.ServiceProcess.ServiceController('Service','server')).WaitForStatus('Running',(new-timespan -seconds 5))

Allright, that’s pretty easy! This gives me a good way to deal with the services, now all I have to do is write a script around it that is easy to use for everyone working on the project.

Time to start thinking about the actions I’m going to implement.

Getting a list of all services, or a filtered list (based on the displayname of a service) is a pretty important function. I can pretty much copy the line from the blogpost mentioned above, but I will also provide the possibility to filter the list.

[System.ServiceProcess.ServiceController]::GetServices($server) | where {$_.DisplayName -match $filter}

To manage the services I’m going to implement start, stop and restart. Let’s do this the clean way and create two functions, startService and stopService, I think this is pretty straightforward.

function startService()
{
    $serviceController = (new-Object System.ServiceProcess.ServiceController($service,$server))
    if($serviceController.Status -notlike 'Running')
    {
        $serviceController.Start()
        $serviceController.WaitForStatus('StartPending', (new-timespan -seconds 10))
        $service + " is starting.."
        $serviceController.WaitForStatus('Running',(new-timespan -seconds 20))
        $service + " is " + $serviceController.Status
    }
    else {Write-Host "$service is already Running."}
}

Now, the server to target and the service to manage can always be different and should be provided by the user of the script. I also need a way to determine which action a user want to perform. When listing the services a filter could be useful. Including some help in the script is probably a good idea. I will use named parameters to implement all this. This should be on the first line in the script.

param([string]$server, [string]$command, [string]$filter, [string]$service, [switch]$help)

There are my parameters, this makes the script a bit universal in it’s use. But this also means a user can provide a service that doesn’t exist. Let’s write a function to check for that.

function checkServiceExists()
{
  if($service -like '')
  {
    Write-Host 'Please provide service name.'
    exit
  }

  $svcexists = 0
  $svcs = [System.ServiceProcess.ServiceController]::GetServices($server);

  foreach($svc in $svcs)
  {
    if($svc.Name -like $service) {$svcexists = 1; break;}
  }
  if(!$svcexists)
  {
    Write-Host 'Service does not exist on remote machine.'
    exit
  }
}

So, I’m checking if the service name contains a value and, if it does, that it exists on the remote machine. Otherwise the script tells the user to edit the parameter. Great!

Now I need to check which action a user wants to perform. This can simply be done using If and ElseIf, it could also be done with the Switch statement. When a user types a command that doesn’t exist, a message will clarify this.

if($command -like '') {}
elseif($command -like 'get')
{
  [System.ServiceProcess.ServiceController]::GetServices($server) | where {$_.DisplayName -match $filter}
}
elseif($command -like 'start')
{
  startService
}
elseif($command -like 'stop')
{
  stopService
}
elseif($command -like 'restart')
{
  stopService
  startService
}
else
{
  Write-Host "'$command' is an invalid command."
}

This PowerShell stuff is actually pretty easy! Now all I need to implement is the help.

if($help)
{
  Write-Host @"

RemoteServiceManager.ps1

Manage services on a remote computer.

Parameters explanation.

"@
  exit
}

The complete ‘manage services remotely’ script

Allright, I now have a working script to remotely manage services, that provides some feedback when users provide wrong information. This will definately be useful in future projects too.

There is still a lot of room for improvements, so feel free to play around with my script and let me know if you add something cool to it. You can download the complete script here.

UPDATE: I updated the code for the file, because it’s changed since first posting this, by adding the help in a standard way and some adjustments here and there.

###################################
##  RemoteServiceManager.ps1     ##
##   by Kevin Pelgrims           ##
##  kevinpelgrims.wordpress.com  ##
##   February 23, 2010           ##
###################################

# Get parameters
param([string]$server, [string]$command, [string]$filter, [string]$service)

# Load ServiceController assembly, if it is not already loaded
if (-not ([appdomain]::CurrentDomain.getassemblies() |? {$_.ManifestModule -like "system.serviceprocess"})) {[void][System.Reflection.Assembly]::LoadWithPartialName('system.serviceprocess')}

# Check if a servicename is given and if the service exists
function checkServiceExists()
{
    if($service -like '')
    {
        "Please provide service name."
        exit
    }

    $svcexists = 0
    $svcs = [System.ServiceProcess.ServiceController]::GetServices($server);
    foreach($svc in $svcs)
    {
        if($svc.Name -like $service) {$svcexists = 1; break;}
    }
    if(!$svcexists)
    {
        "Service does not exist on remote machine."
        exit
    }
}

# Start the service, if it is not already running
function startService()
{
    checkServiceExists
    $serviceController = (new-Object System.ServiceProcess.ServiceController($service,$server))
    if($serviceController.Status -notlike 'Running')
    {
        $serviceController.Start()
        $serviceController.WaitForStatus('StartPending', (new-timespan -seconds 10))
        $service + " is starting.."
        $serviceController.WaitForStatus('Running',(new-timespan -seconds 20))
        $service + " is " + $serviceController.Status
    }
    else {"$service is already Running."}
}

# Stop the service, if it is not already stopped
function stopService()
{
    checkServiceExists
    $serviceController = (new-Object System.ServiceProcess.ServiceController($service,$server))
    if($serviceController.Status -notlike 'Stopped')
    {
        $serviceController.Stop()
        $serviceController.WaitForStatus('StopPending', (new-timespan -seconds 10))
        $service + " is stopping.."
        $serviceController.WaitForStatus('Stopped',(new-timespan -seconds 20))
        $service + " is " + $serviceController.Status
    }
    else {"$service is already Stopped."}
}

# Check the command parameter to determine the action to be undertaken
if($command -like '') {}
elseif($command -like 'get')
{
    [System.ServiceProcess.ServiceController]::GetServices($server) | where {$_.DisplayName -match $filter}
}
elseif($command -like 'start')
{
    startService
}
elseif($command -like 'stop')
{
    stopService
}
elseif($command -like 'restart')
{
    stopService
    startService
}
else
{
    "'$command' is an invalid command."
}

<#

.SYNOPSIS
RemoteServiceManager.ps1

Manage services on a remote computer.

Input:
  None.

Output:
  None.

Parameters:
  server             - Name of the remote machine on which commands should be executed
  command            - The command that should be executed
                       Available commands: get, start, stop, restart
  filter             - Filter on DisplayName for "get" command
  service            - Name of the service

.DESCRIPTION
Manage services on a remote computer.

.LINK

https://kevinpelgrims.wordpress.com

#>

Read Full Post »

Blog is moving! You should check this post out on kevinpelgrims.com

What is PowerShell?

PowerShell is an object-oriented programming language and interactive command line shell for Microsoft Windows that is built on top of the .NET framework.

It was designed to automate system tasks and create systems management tools for commonly implemented processes.

PowerShell offers a variety of ways to automate tasks, including:

  • Cmdlets, which are very small .NET classes that appear as system commands.
  • Scripts, which are combinations of cmdlets and associated logic.
  • Executables, which are standalone tools.
  • Instantiation of standard .NET classes.

PowerShell integrates with the .NET environment and can also be embedded within other applications. Over a hundred cmdlets are included that can be used separately or combined with others to automate more complex tasks. Users can also create and share cmdlets.

PowerShell 2.0 is installed by default with Windows 7 and Windows Server 2008 R2. It has also been released for older platforms, i.e.Windows XP SP3, Windows Server 2003 SP2, Windows Vista SP1 and Windows Server 2008.

Some good info on PowerShell in general can be found on Wikipedia: http://en.wikipedia.org/wiki/Windows_PowerShell

What are the cool new features of version 2.0?

PowerShell 2.0 has a lot of great improvements over version 1.0, listed here are some of the more important new features.

  • Remoting

PowerShell 2.0 lets you run commands on one or many remote computers with a single Windows PowerShell command. You can run individual commands, or you can create a persistent connection (a session) to run a series of related commands. You can also start a session with a remote computer so that the commands you type run directly on the remote computer.

The remoting features of Windows PowerShell are built on Windows Remote Management (WinRM).

  • Windows PowerShell ISE and debugger

PowerShell 2.0 includes Windows PowerShell Integrate Scripting Environment (ISE), an application that lets you run commands, and design, write, test, and debug scripts in a graphical,  color-coded environment. It does not contain code completion, as opposed to PowerGUI.

PowerShell 2.0 also includes a debugger for scripts and functions. You can add breakpoints and display the call stack.

  • Background jobs

Background jobs are commands that run asynchronously. When you run a background job, the command prompt returns immediately, even if the command is still running. You can use the background job feature to run a complex command in the background so that you can use your session for other work while the command runs.

  • Lots and lots of new Cmdlets!

There are 107 new Cmdlets in PowerShell 2.0 for you to play with. Ranging from Cmdlets to take advantage of the new Remoting capabilities to Computer Management and WS-Management Cmdlets.

  • Event notification

Users can register and subscribe to events, such as Windows PowerShell events, WMI events, or .NET Framework events. And users can listen, forward, and act on management and system events both synchronously and asynchronously.

  • Modules

Modules let you divide and organize your PowerShell scripts into independent, self-contained, reusable units. Code from a module executes in its own context, so it does not conflict withthe variables, functions and other resources in the session.

  • Transactions

Transactions let you undo an entire series of operations. They are available only for operations that support transactions. Transactions are designed for applications that require atomicity, consistency, isolation and recoverability, like databases and message queuing.

  • And a lot more..

There are a whole lot more new features in version 2.0, you can find more information at the resources below.

Installing PowerShell

Installing PowerShell 2.0 is pretty straightforward, just run the installer. If you want to use the remoting feature, be sure to install PowerShell 2.0 on all machines.
Here is the link: http://support.microsoft.com/kb/968929 (it’s all there at the bottom of the page).

Resources

A list of resources on PowerShell 2.0:

Read Full Post »