You are currently browsing the archives for the PowerShell category.

Archive for the ‘PowerShell’ Category

A whole bunch of stuff with Service Manager

 :: Posted by John Savill on 05-24-2014

It started out very simple. I was preparing for a client that wanted to allow business groups to schedule the deployment of patches to their servers via Configuration Manager using Orchestrator and Service Manager with some approval workflow. This seemed the right approach and I decided to quickly setup a little example of what this would look like but instead of using Configuration Manager I decided to just be able to run any PowerShell command on the computers in the passed Active Directory group (which contained the computers for that business group). The final solution is walked through at http://youtu.be/RFLhyMhJOOc and I have a bunch of assets listed below:

The example runbook is available at http://www.savilltech.com/videos/RunActivity.ois_export

The example PowerShell is available at http://www.savilltech.com/videos/RunCommand.ps1

The example email approval template is available at http://www.savilltech.com/videos/RequestApproval.txt

I wanted to briefly go over the key steps here that are walked through in the video:

Firstly I decided to do the actual logic of finding all the machines in the passed AD group using PowerShell and within the PowerShell actually perform the actions. You could have done this with Service Manager activities but the direction is PowerShell so I decided to implement the main logic in PowerShell but use Orchestrator activities for interacting with Service Manager such as update Service Request status etc. The basic PowerShell is below:

$ADGroupName = “FileServicesGroup”
$CommandToRun = “mkdir c:\johntest”

$ScriptBlockContent = {
param ($CommandToRun)
Invoke-Expression $CommandToRun }

$ADGroupMembers = Get-ADGroupMember -Identity $ADGroupName
foreach ($computer in $ADGroupMembers)
{
#Run the required command on each computer in the group
Invoke-Command -ComputerName $computer.name -ScriptBlock $ScriptBlockContent -ArgumentList $CommandToRun
}

In this basic PowerShell I am hardcoding the AD group and the command to run but when it gets into Orchestrator I’ll replace that with the information sent from Service Manager. Note I use a parameter to pass to the scriptblock since the actual variable is local to my PowerShell session and NOT the one I create remotely on each machine.

I then create a runbook in Orchestrator which essentially uses this PowerShell which also hooks into Service Manager to update the Service Request status.

In Service Manager I synchronize with Orchestrator to get the Runbook in the library then create a Runbook Automation Activity template and then a new Service Request template which has two activities. The first is a review activity which is for the submitting users line manager (as defined in Active Directory) and the second calls the Runbook Automation Activity template and defines the Runbook ID (RBId) and the Service Request ID (SRId) which is the Work Item – ID for each of the respective values. This is shown below.

IdMappinginSRTemplateforRBActivity

Because when this all runs via Orchestrator it runs as the Orchestrator service account I made the Orchestrator service account a local administrator on each server using the Group Policy Preferences local group feature and added the service account. Other options could have been to specify a credential as part of the actual Invoke-Command within the PowerShell but I liked the Group Policy option.

gpoadmin

I wanted to use Office 365 and I walk through the basic steps in a FAQ at http://windowsitpro.com/service-manager/connect-service-manager-office-365

I created email templates for the review activity and notification the Service Request is complete and then configured those to be used as part of the workflows.

I created Request Offerings and Service Offerings and the key point is for end users to see them I created new Catalog Groups, one for Request Offerings and one for Service Offerings that dynamically added all published of each type. I then created a new User Role that was for all Domain Users that included both those new Catalog Groups.

I then walk through it all!

AGAIN DO NOT DEPLOY THIS IN PRODUCTION.

THE ABILITY FOR ANY USER TO RUN ANY COMMAND ON EVERY SERVER IN A PASSED GROUP IS VERY BAD. THIS WAS AN EXAMPLE ONLY !!!!

This is an example only and you should modify the actions performed in Orchestrator to your own specific needs.

And the video:

New Storage Spaces in Windows Server 2012 R2 Video

 :: Posted by John Savill on 07-06-2013

In the video below I whiteboard the new features of Windows Server 2012 R2 Storage Spaces and then perform a full demo using PowerShell in my lab. http://youtu.be/x8KlY-aP9oE

Below is all the code I use.

New video on the new features of PowerShell 3.0

 :: Posted by John Savill on 05-17-2013

Sat down this morning and created a new video on the major new features of PowerShell 3.0. It’s uploaded to YouTube and available at http://youtu.be/aQgptbNOBBo. Plus the main code I use throughout the video so you can try for yourself!

#region CIM
Get-Command -Module CimCmdlets
Get-CimClass -ClassName *disk*
Get-CimClass win32* -MethodName Term*
Get-CimInstance Win32_Process
#endregion

#region Simplification example
Get-Process | where {$_.HandleCount -gt 900}
Get-Process | where {$psitem.HandleCount -gt 900}
Get-Process | where HandleCount -gt 900
#endregion

#region Robust sessions
$RemoteSession = New-PSSession –Name Server1Session –ComputerName savdaldc01
Invoke-Command –Session $RemoteSession –ScriptBlock {$date = Get-Date}
Disconnect-PSSession –session $RemoteSession

#This would then be run on the savdaldc01 machine locally showing state not lost
Get-PSSession –ComputerName localhost
$LocalSession = Connect-PSSession –ComputerName localhost  –Name Server1Session
Invoke-command –Session $LocalSession –Scriptblock { $date }
Get-PSSession –ComputerName localhost | Remove-PSSession
#endregion

#region Workflow
Workflow MyWorkflow {Write-Output -InputObject “Hello from Workflow!”}
Get-Command –Name MyWorkflow –Syntax
MyWorkflow

Workflow LongWorkflow
{
Write-Output -InputObject “Loading some information…”
Start-Sleep -Seconds 10
CheckPoint-Workflow
Write-Output -InputObject “Performing some action…”
Start-Sleep -Seconds 10
CheckPoint-Workflow
Write-Output -InputObject “Cleaning up…”
Start-Sleep -Seconds 10
}

LongWorkflow –AsJob –JobName LongWF
Suspend-Job LongWF
Get-Job LongWF
Receive-Job LongWF –Keep
Resume-Job LongWF
Get-Job LongWF
Receive-Job LongWF –Keep
Remove-Job LongWF
#endregion

#region Background job
$Trigger = New-JobTrigger –Daily –At 2am
Register-ScheduledJob –Name MyScheduledJob –ScriptBlock {Get-Process} –Trigger $Trigger
Get-ScheduledJob
(Get-ScheduledJob –Name MyScheduledJob).JobTriggers
Get-ScheduledJob –Name MyScheduledJob
Unregister-ScheduledJob -Name MyScheduledJob
#endregion

#region Misc commands
Get-Command *disk*
Get-Module Get-Disk
Get-Module Show-Command
Get-Command | sort Module | out-gridview
#endregion