All posts by brad@wernerconsulting.com

Late Night with System Center Management

It’s 3:30 a.m. and your trusty mobile phone on your nightstand buzzes a hideous, nasty, telltale racket. You pick up the smartphone and squint in the darkness at the glowing message that informs you that one of the e-mail servers at work is down. As you’re about to dismiss the nasty-gram in your still-half-asleep daze (who would need e-mail at 3:30 in the morning?), you bolt up wide-eyed! You suddenly realize the server that’s down serves critical e-mail services for a team three time zones east of you. And, at 6:30 a.m. their time, a downed server spells near-immediate and definitely impending doom as the workforce at that facility is about to start their shift.

A few years ago, with car keys in hand, you would have been racing for the door to get to work. Last year, you might have fired up the laptop or tablet, gotten on the VPN, and performed a bit of remote management magic to try to remedy the situation. But now, you read the choices presented on your phone: Restore Server, Switch to DR Site, Restart Server. You make your selection, receive near-instant confirmation and a new health update, and begin fantasizing about starring in yet another Walter Mitty-esque “Masters of System Center 2012″ episode as you drift back into dreamland.
A student in one of my Microsoft System Center 2012 Private Cloud courses recently asked about the ability to receive notifications regarding system health on his smartphone. It started off as a question that dozens of others have asked. One easily answered and easily handled by System Center 2012’s Operations Manager. However, this person pointed out that he also wanted to go beyond merely receiving a notification of the alert. He wanted to initiate a change from his phone that would either simply acknowledge the alert or initiate corrective actions. One of the goals was to be able to clear an alert on his phone and have both System Center Operations Manager (SCOM) close the alert and System Center Service Manager (SCSM) resolve the related incident. Having SCOM and SCSM work together to couple actions on alerts and incidents is a feature supported on the connectors in System Center 2012. The system management magic is getting the mobile phone involved as desired.

Of course, I mentioned that Windows PowerShell or System Center Orchestrator could be used to help accomplish this, but then a discussion started around using third-party tools to provide this sort of automation as another approach. After a bit of research, I provided them with the link to an April 2012 article by Peter Stevens, “Enterprise Alert and System Center 2012,” that describes such a product called Enterprise Alert 2012 from Derdack of Berlin, Germany.

In the article, Stevens includes a description of the add-on product to System Center. While you could write your own System Center 2012 Orchestrator runbooks and PowerShell scripts and configure the appropriate notification channels in SCOM and SCSM to accomplish much of what this product does, this product delivers an off-the-shelf foundation enabling you to focus on how you want to manage your systems rather than having to create the magic glue and integration between Orchestrator and other key System Center components.

But as pointed out in the YouTube video that Stevens included in his article, one of the best features of this product is its Enterprise Alert Integration Pack for System Center 2012 Orchestrator. Some of the activities included in the integration pack are:
• E-Mail Notification
• Flag for Mobile Execution
• Instant Message Notification (Lync)
• Multi-Channel Notification
• Smartphone Push Notification
• SMS Text Notification
• Voice Call Notification

Of these different Orchestrator activities, the most exciting is Flag for Mobile Execution. When you add that activity into a runbook, without even connecting it with links to other activities (it can just sit next to the Initialize Data activity if you want), the runbook becomes registered as available to mobile devices in response to a notification! I suggest watching the demonstration video to see how easy avoiding a late-night drive to work could be. Of course, Orchestrator can accomplish other magic on its own, but for remote smartphone management, this is an immensely powerful toolkit.

How much would your organization be willing to spend for this sort of functionality? According to the Derdack site, a license to their Enterprise Alert® System Center Edition retails for US $7,995. Each Alert User Client Access License runs US $399 at the time of this writing. Note also that they offer an Open API Edition, also for $7,995, that allows systems, including but not limited to Nagios, Solarwinds, CA, and BMC, to leverage off their notification and action infrastructure. Enterprise Alert makes this kind of notify-and-respond functionality available on smartphones such as iPhone, Windows Phone, Blackberry, and Android. The integration with System Center 2012 Orchestrator, Operations Manager, and Service Manager affords auditing, integration with other processes, and extensibility. This technology can be utilized in private cloud deployments and any other environments that use System Center 2012.

They say that a good night’s sleep is priceless, but with Enterprise Alert there may be a nominal price! What other suggestions do you have for providing such System Center 2012 remote management functionality? I’m sure there are other solutions out there, and I’d love to hear from you.

NOTE: This article was posted on September 20, 2013 to the Global Knowledge Training Blog at <http://blog.globalknowledge.com/technology/microsoft/late-night-with-system-center-management/>

PowerShell Data Type Basics

Yellow Binary Byte 42

A year ago? A year and a half ago? Yes, that is how old some of the notes are that I left myself, after students asked for a list of the basic data types available in Windows PowerShell. I honestly thought I had blogged about this long ago. This article provides a foundation for several others. The question which has prompted this is one of several which people tend to ask during PowerShell courses.

What data types are available in Windows PowerShell?

Is there a list of these?

The quick answers to these are yes there is a list, and then I typically direct students to the Microsoft Developer Network (MSDN) .NET type reference pages. Here, we shall look at more specific answer which hopefully ties together several aspects of PowerShell and .NET data types that might not be clear from reading any one particular page on MSDN, TechNet, or various other PowerShell blogs or references. I hope that this helps. Please let me know if you would like any additional information.

If you are interested in PowerShell but either have no background or no interest in programming in C#, F#, J#, Visual Basic (VB), or any other the other lovely .NET programming languages, you may find that much of the .NET type information is not exactly Greek, but tends to be C# oriented, which many people have told me is disconcerting when they really just want to focus on Windows PowerShell.

First, it is good to note, before we get mired in details, that PowerShell typically does not require you to specify data types, but will automagically coerce values into the necessary underlying data types. Later, we’ll look at PowerShell as a Calculator, which strives to drive home this point. In summary, you usually don’t need to worry about data types in PowerShell, as they are handled transparently so that us humans do not have to be concerned with those gory details.

If you are concerned with the gory details for whatever reason, read on!

In Windows PowerShell, data types can be explicitly specified in several scenarios:

  • After the New-Object cmdlet name, a data type name can be given to create an instance (object) of that type.
  • Inside square brackets, a type name could be used to access a static (class) method or property.
  • Inside square brackets, a type name could be used to cast (convert) a value into that data type.

One of the first data types that people like to introduce is the integer data type, which in .NET is called Int32 starting with a capital I, in C# this is simply int with a lowercase i, and in the class method and casting uses in PowerShell is most often written in square brackets as lowercase int similar to C#, as follows: [int].

Note that PowerShell is flexible, and instead of using the C# notation int in square brackets, [int], you could refer to the .NET name within the System namespace by using the notation: [System.Int32], or even without the System namespace explicitly identified, as just [Int32]. Notice the capital I again in Int32. Also, because PowerShell is particularly forgiving with respect to case sensitivity, being largely case insensitive, unlike C#, we would also use [int32] or [system.int32] as well, or even [INT], [INT32], or [SYSTEM.INT32].

Real numbers which have a fractional part after the decimal point are a different data type, as shown by the result of the following logical expression:

PS C:> 42 -eq 42.1234
False

The -eq operator checks for equality of the operands, 42 on the left, and 42.1234 on the right. They are not equal, thus the result of the -eq operator is the boolean value False.

If we include a cast of the right-hand side to an integer value prior to the comparison, we have equality. Let’s look at this using two similar ways of specifying an integer cast in PowerShell:

PS C:> 42 -eq [int]42.1234
True
PS C:> 42 -eq [System.Int32]42.1234
True

Rather than dive deeper into casting, operators, expressions, and scenarios of when and how we could use explicit data types in Windows PowerShell, let’s get back to the original questions.

What are the data types available in Windows PowerShell? There are thousands by default, and you can easily add dozens, hundreds, or thousands more by bringing in additional software to be accessed and/or managed via PowerShell. Here is a brief and by no means exhaustive list of a small very few of the primitive types in PowerShell with a few commonly used non-primitive ones thrown in at the end of the list. Note that the use of the System namespace and the dot which separates that from the class/type name for the first two was used intentionally.

[System.Object]
[System.ValueType]
[void]
[bool]
[enum]
[byte]
[sbyte]
[int16]
[uint16]
[char]
[int]
[int32]
[uint32]
[float]
[single]
[long]
[int64]
[uint64]
[double]
[DateTime]
[decimal]
[guid]
[array]
[string]
[hashtable]
[random]
[regex]
[XML]
[WMI]
[WMICLASS]
[ADSI]

Consider the following PowerShell command snapshot, which is transcribed beneath the graphic and rendered as text for clarity.

2013w10-PowerShell-Types

Here is the same thing in a larger typeface (font) as text, just the one-line command first.

PS C:> [object],[valuetype],[void],[bool],[byte],[int],[long],[single],[double],[datetime],[decimal],[guid],[array],[string],[hashtable],[random],[regex],[PSObject],[XML],[WMI],[WMICLASS],[ADSI],[Diagnostics.Process],[ServiceProcess.ServiceController],[IO.FileInfo],[IO.DirectoryInfo] | FT Name,IsClass,IsValueType,UnderlyingSystemType,BaseType -auto

Note that in this example, we did not include the System namespace before each of the data types. Now, let’s look at the results.

Name IsClass IsValueType UnderlyingSystemType BaseType
Object True False System.Object 
ValueType True False System.ValueType System.Object 
Void False True System.Void System.ValueType
Boolean False True System.Boolean System.ValueType
Byte False True System.Byte System.ValueType
Int32 False True System.Int32 System.ValueType
Int64 False True System.Int64 System.ValueType
Single False True System.Single System.ValueType
Double False True System.Double System.ValueType
Decimal False True System.Decimal System.ValueType
Guid False True System.Guid System.ValueType
Array True False System.Array System.Object 
String True False System.String System.Object 
Hashtable True False System.Collections.Hashtable System.Object 
Random True False System.Random System.Object 
Regex True False System.Text.RegularExpressions.Regex System.Object 
PSObject True False System.Management.Automation.PSObject System.Object 
XmlDocument True False System.Xml.XmlDocument System.Xml.XmlNode 
ManagementObject True False System.Management.ManagementObject System.Management.ManagementBaseObject 
ManagementClass True False System.Management.ManagementClass System.Management.ManagementBaseObject 
DirectoryEntry True False System.PSObject System.Object 
Process True False System.PSObject System.Object 
ServiceController True False System.PSObject System.Object 
FileInfo True False System.PSObject System.Object 
DirectoryInfo True False System.PSObject System.Object

PowerShell and GUIDs

Interdum at. Eget habitasse elementum est, ipsum purus pede porttitor class, ut adipiscing, aliquet sed auctor, imperdiet arcu aliquam maecenas ligula nostra tempor fermentum. Ligula suspendisse nulla pretium, rhoncus tempor placerat. Lorem ipsum dolor sit amet, ligula suspendisse nulla pretium, rhoncus tempor placerat fermentum, enim integer ad vestibulum volutpat. Nisl rhoncus turpis est, vel elit, congue wisi enim nunc ultricies sit, magna tincidunt. Maecenas aliquam maecenas ligula nostra, accumsan taciti.

Sociis mauris in integer, a dolor netus non dui aliquet, sagittis felis sodales, dolor sociis mauris, vel eu libero cras. Interdum at. Eget habitasse elementum est, ipsum purus pede porttitor. Interdum at. Eget habitasse elementum est, ipsum purus pede porttitor class, ut adipiscing, aliquet sed auctor, imperdiet arcu aliquam maecenas ligula nostra tempor fermentum. Ligula suspendisse nulla pretium, rhoncus tempor placerat.

Lorem ipsum dolor sit amet, ligula suspendisse nulla pretium, rhoncus tempor placerat fermentum, enim integer ad vestibulum volutpat. Nisl rhoncus turpis est, vel elit, congue wisi enim nunc ultricies sit, magna tincidunt. Maecenas aliquam maecenas ligula nostra, accumsan taciti. Sociis mauris in integer, a dolor netus non dui aliquet, sagittis felis sodales, dolor sociis mauris, vel eu libero cras. Interdum at. Eget habitasse elementum est, ipsum purus pede porttitor. Interdum at. Eget habitasse elementum est, ipsum purus pede porttitor class, ut adipiscing, aliquet sed auctor, imperdiet arcu aliquam maecenas ligula nostra tempor fermentum. Ligula suspendisse nulla pretium, rhoncus tempor placerat. Lorem ipsum dolor sit amet, ligula suspendisse nulla pretium, rhoncus tempor placerat fermentum, enim integer ad vestibulum volutpat. Nisl rhoncus turpis est, vel elit, congue wisi enim nunc ultricies sit, magna tincidunt. Maecenas aliquam maecenas ligula nostra, accumsan taciti. Sociis mauris in integer, a dolor netus non dui aliquet, sagittis felis sodales, dolor sociis mauris, vel eu libero cras. Interdum at. Eget habitasse elementum est, ipsum purus pede porttitor.

More on multiple elements per ASP.NET Web Form

2013w06-WebFormPlurality-bothServerCode

I recently wrote a note about several possible solutions to simulating multiple web forms on the same page when using ASP.NET Web Forms, to work around the restriction of one active (visible) ASP.NET <form> per .aspx page. Although a good article by Kirk Evans titled “Neat ASP.NET Trick: Multiple Forms on a Page” shows the technique, I wanted to elaborate with some more step-wise details.

First, what I had described earlier as option #2, is shown in the listing at the top of this page. Note that the <form id=”form2”> has only classic HTML <input> items used literally. Although these are the exact kinds of elements that ASP.NET will generate in the rendering phase for “form1” in that example, ASP.NET does not allow multiple server-side forms on the same Web Form (i.e. .aspx file). This yields the following visual result, which unfortunately does not functionally do what the button text implies.

2013w06-WebFormPlurality-shot2

Rather than focusing on making that functional via JavaScript or other techniques, let us focus on what I had described as option #1 in the earlier blog post, with a step-wise approach.

Although having two or more <form> elements on the same ASP.NET Web Form throws an exception if two or more server-side <form> elements are visible, as Evans had pointed out, we can make all but one of those forms invisible as follows:

2013w06-WebFormPlurality-bothServerOneVisibleCode

This results in only the first form being visible, but it loads without the exception.

2013w06-WebFormPlurality-bothServerOneVisibleFirst

If you add behavior to the button to switch the visibility of both forms, then you can switch from form1 to form2 at the press of a button.

2013w06-WebFormPlurality-bothServerOneVisibleCode1

Of course, in a real form, you would likely have logic to process the information from the form, however only the visibility switching code is shown here for clarity. Pressing the button makes form1 disappear and form2 magically appears (it isn’t really magic, it’s just the changing in the rendering based on those two form1.Visible and form2.Visible properties above).

2013w06-WebFormPlurality-bothServerOneVisibleSecond

You could add exactly the reverse action into the Button2_Click event handler wired up to this button as follows:

2013w06-WebFormPlurality-bothServerOneVisibleCode2

The WebPlurality.aspx markup shows the onclick wiring of the event handlers to these events for the appropriate buttons.

2013w06-WebFormPlurality-bothServerOneVisibleCode3

Now, the user of the web form can switch from form1 to form2 and back as many times as are necessary to the same URL for the WebFormPlurality.aspx and they alternate between the two ASP.NET server-side forms. Certainly, other events besides buttons firing could be used to trigger the alternation between the forms.

Perhaps you are wondering what benefits are afforded by sharing the same .aspx file (ASP.NET Web Form) for two forms. Consider that the view state and use of one Page class is used. Although different instances of that class may be used for each postback, however having the same class code loaded into the web host has its benefits. But the benefits of sharing the same view state for two or more forms within the same ASP.NET Web Form has many implications for JavaScript scripting and AJAX interactions as well, not just better continuity for processing postbacks. The topic of benefits of doing this deserves its own topic. Let me know if you’re interested in more details. For now, let’s get back to the mechanics of switching between web forms sharing the same .aspx file.

Again, there are many ways in which the switching between the forms could be accomplished. One technique shown thus far is to have the onclick event handlers for the buttons do the visibility switcheroo of the forms. One of the possible alternatives is to have the Page_Load method switch them, as Mr. Evans’ article had suggested. The result would resemble the listing below.

2013w06-WebFormPlurality-bothServerOneVisibleCode4

As written, this code will switch between two forms, where one had been visible previous and the other not visible, it simply inverts the visible of each. For three or more forms this would need to be modified with some sort of signal, request or pecking order, thus the button-driven approach can have its advantages for three or more forms. One problem with this Page_Load visibility swap technique even for two forms. Because form1 was initially visible and form2 was not, this Page_Load method implementation depicted above actually shows form2 first, then allows switching to form1, which might not be what had been intended by the designer who had set up form1 to be visible in the .aspx markup. Luckily, there is a simple fix for that feature.

2013w06-WebFormPlurality-bothServerOneVisibleCode5

Before discussing that fix, let’s clean up the code by removing the Button1_Click and Button2_Click methods, and then scrubbing the wiring of the onclick= attribute to those from each of the buttons in the markup. The above version of the WebFormPlurality.aspx shows this. Now, on to that other fix with the Page_Load method.

2013w06-WebFormPlurality-bothServerOneVisibleCode6

Note that the above version of WebFormPlurality.aspx.cs has an if( IsPostBack ) clause with the body being the swapping of the visibility. This accomplishes the goal of retaining the states of the visibility set in the .aspx markup file upon initial load, and inverts only on postbacks, whether they are caused by button actions or other events which trigger postbacks to the page.

As in Mr. Evans’ example, the last two listings would be sufficient to illustrate that the visibility can be swapped between two <form runat=”server”> elements on the same .aspx Web Form. However, the sequence shown in this article has given us the opportunity to mention some of the other possible ways of implementing something similar as well as hint at some of the ramifications and related tangential possibilities. What might you use such a technique for? Or what have you used such a technique to accomplish already?

ASP.NET: A page can have only one server-side Form tag

2013w06-WebFormPlurality-bothServerErrorSmall

A student in a Microsoft ASP.NET web development class recently asked the following question:

 I have a Perl webpage that has multiple forms on it, like this:

<body>
    <form id=forma1></form>
    <form id=form2></form>
</body>

I have tried to do the same thing in ASP.NET and C# with the runat=”server” attribute in the forms, and cannot get it to run.

That’s an excellent question. There is bad news and good news; first, the bad. Unfortunately, ASP.NET “owns” the form so that only one *VISIBLE* server-side form can be on any one .aspx file’s Web Form at a time.

Luckily, there are several workarounds or solutions which might give you what you want.

(1) Here is an article <http://blogs.msdn.com/b/kaevans/archive/2005/10/19/482778.aspx> by Kirk Evans titled “Neat ASP.NET Trick: Multiple Forms on a Page”. There are many references at other web sites as well which convey the fact that you can’t have more than one HTML <form> with the runat=”server” on the same page, however Kirk Evans presents an example where you could Switch Between Two Forms, as opposed to some other authors who simply say it is impossible.

(2) You could have one ASP.NET <form id=”form1″ runat=”server”></form> and another one or more without the runat=”server” such as <form id=”form2″></form>, however you can’t effectively have ASP.NET elements which are processed on the server-side in the second or subsequent forms. It depends on your needs and what you wanted to do with those forms with respect to client-side and server-side processing as to whether that solution is viable.

(3) You could use User Controls with .ascx files and have more than one of them composed on the same ASP.NET Web Form (.aspx file). This technique is pretty straight forward, and is one of my preferred methods for solving this sort of problem.

(4) You could use multiple buttons which act as submit buttons for different sets of controls/fields on the same form, but the C# (or other) code behind the markup treats the fields in distinct sets so that it is almost like having two forms.

(5) You could use update panels with ASP.NET AJAX.

I hope that helps. To all you in the blogosphere, do these options make sense?

Thanks,
++brad;

Back to Blogging

noteGlyph i15

 

Greetings!

It has been a while since I have written any entries in this blog. My February resolution is to share some of the thoughts and questions which have come my way over the interim, as well as new questions from students, customers, and people I come across out in the world.

I hope that you enjoy the rebirth of this blog!

Thanks,

++brad;

Group Policy All Over Again

Interdum at. Eget habitasse elementum est, ipsum purus pede porttitor class, ut adipiscing, aliquet sed auctor, imperdiet arcu aliquam maecenas ligula nostra tempor fermentum. Ligula suspendisse nulla pretium, rhoncus tempor placerat. Lorem ipsum dolor sit amet, ligula suspendisse nulla pretium, rhoncus tempor placerat fermentum, enim integer ad vestibulum volutpat. Nisl rhoncus turpis est, vel elit, congue wisi enim nunc ultricies sit, magna tincidunt. Maecenas aliquam maecenas ligula nostra, accumsan taciti.

Sociis mauris in integer, a dolor netus non dui aliquet, sagittis felis sodales, dolor sociis mauris, vel eu libero cras. Interdum at. Eget habitasse elementum est, ipsum purus pede porttitor. Interdum at. Eget habitasse elementum est, ipsum purus pede porttitor class, ut adipiscing, aliquet sed auctor, imperdiet arcu aliquam maecenas ligula nostra tempor fermentum. Ligula suspendisse nulla pretium, rhoncus tempor placerat.

Lorem ipsum dolor sit amet, ligula suspendisse nulla pretium, rhoncus tempor placerat fermentum, enim integer ad vestibulum volutpat. Nisl rhoncus turpis est, vel elit, congue wisi enim nunc ultricies sit, magna tincidunt. Maecenas aliquam maecenas ligula nostra, accumsan taciti. Sociis mauris in integer, a dolor netus non dui aliquet, sagittis felis sodales, dolor sociis mauris, vel eu libero cras. Interdum at. Eget habitasse elementum est, ipsum purus pede porttitor. Interdum at. Eget habitasse elementum est, ipsum purus pede porttitor class, ut adipiscing, aliquet sed auctor, imperdiet arcu aliquam maecenas ligula nostra tempor fermentum. Ligula suspendisse nulla pretium, rhoncus tempor placerat. Lorem ipsum dolor sit amet, ligula suspendisse nulla pretium, rhoncus tempor placerat fermentum, enim integer ad vestibulum volutpat. Nisl rhoncus turpis est, vel elit, congue wisi enim nunc ultricies sit, magna tincidunt. Maecenas aliquam maecenas ligula nostra, accumsan taciti. Sociis mauris in integer, a dolor netus non dui aliquet, sagittis felis sodales, dolor sociis mauris, vel eu libero cras. Interdum at. Eget habitasse elementum est, ipsum purus pede porttitor.

Remote Parameters in PowerShell

object356

Interdum at. Eget habitasse elementum est, ipsum purus pede porttitor class, ut adipiscing, aliquet sed auctor, imperdiet arcu aliquam maecenas ligula nostra tempor fermentum. Ligula suspendisse nulla pretium, rhoncus tempor placerat. Lorem ipsum dolor sit amet, ligula suspendisse nulla pretium, rhoncus tempor placerat fermentum, enim integer ad vestibulum volutpat. Nisl rhoncus turpis est, vel elit, congue wisi enim nunc ultricies sit, magna tincidunt. Maecenas aliquam maecenas ligula nostra, accumsan taciti.

Sociis mauris in integer, a dolor netus non dui aliquet, sagittis felis sodales, dolor sociis mauris, vel eu libero cras. Interdum at. Eget habitasse elementum est, ipsum purus pede porttitor. Interdum at. Eget habitasse elementum est, ipsum purus pede porttitor class, ut adipiscing, aliquet sed auctor, imperdiet arcu aliquam maecenas ligula nostra tempor fermentum. Ligula suspendisse nulla pretium, rhoncus tempor placerat.

Lorem ipsum dolor sit amet, ligula suspendisse nulla pretium, rhoncus tempor placerat fermentum, enim integer ad vestibulum volutpat. Nisl rhoncus turpis est, vel elit, congue wisi enim nunc ultricies sit, magna tincidunt. Maecenas aliquam maecenas ligula nostra, accumsan taciti. Sociis mauris in integer, a dolor netus non dui aliquet, sagittis felis sodales, dolor sociis mauris, vel eu libero cras. Interdum at. Eget habitasse elementum est, ipsum purus pede porttitor. Interdum at. Eget habitasse elementum est, ipsum purus pede porttitor class, ut adipiscing, aliquet sed auctor, imperdiet arcu aliquam maecenas ligula nostra tempor fermentum. Ligula suspendisse nulla pretium, rhoncus tempor placerat. Lorem ipsum dolor sit amet, ligula suspendisse nulla pretium, rhoncus tempor placerat fermentum, enim integer ad vestibulum volutpat. Nisl rhoncus turpis est, vel elit, congue wisi enim nunc ultricies sit, magna tincidunt. Maecenas aliquam maecenas ligula nostra, accumsan taciti. Sociis mauris in integer, a dolor netus non dui aliquet, sagittis felis sodales, dolor sociis mauris, vel eu libero cras. Interdum at. Eget habitasse elementum est, ipsum purus pede porttitor.

PowerShell Pre-and-Post-Increment-and-Decrement

object357

Many people have told me that they find PowerShell’s syntax to be confusing. Reading other people’s scripts can be daunting, whether those scripts were download from someone’s blog, written by one of your colleagues or predecessors, or even something written by your past self.

That head-spinning, queasy, brain-full-like-a-sponge-ready-to-be-squeezed nausea and vertigo can be further compounded, and your efforts potentially confounded, by syntactic descriptions in Backus-Naur Form (BNF) notation examples such as those shown in Get-Command and Get-Help and on various supposedly helpful web sites. But most of all, many people find PowerShell syntax confusing because PowerShell is a technology with a long, twisted, and tangled ancestry. From shells and script processors such as sh, awk, perl, and more, and programming languages such as B, C, C++, Java, and C#, the influences on PowerShell are diverse, and carry with them many decades of legacy. With many RT11, CP/M, DOS, Windows Command Prompt (cmd.exe), and even DEC DCL concepts and syntax interwoven with UNIX shell and command environments, and some newer Microsoft .NET influences comingled together, there are often many ways to do or express the same task.

Configuring Group Policy Refresh Interval

Many Group Policy administrators may be tempted to use the graphical Group Policy Management Console (GPMC) to manage which group policy objects (GPOs) are linked to which Active Directory sites, domains, and organizational units (SDOU), governing scope of management, and furthermore prone to use the Group Policy Management Editor (GPME) to manipulate the settings within said group policy objects.

A useful alternative is to use the Group Policy module of Windows PowerShell. Consider the following examples of how to configure a particular Group Policy setting, the “Group Policy Refresh Interval for Computers” in the Computer Configuration half of a GPO.

First, it’s useful to make sure the GroupPolicy module is loaded into PowerShell. You must first have the module available to be loaded on your computer. On domain controllers this is typically a non-issue, however on management workstations, the Remote Server Administration Tools (RSAT) components related to Group Policy Management should be properly installed before proceeding with any such scripts or interactive use of the following PowerShell commands.

if( @(Get-Module GroupPolicy).count -eq 0 ){ Import-Module GroupPolicy }
function List-GPO {Get-GPO -All | Select displayName,description }
function Config-RefreshInterval( 
    $gpo = "IT Policy for Workstations" ){
    Get-GPRegistryValue $gpo -Key   HKLMSoftwarePoliciesMicrosoftWindowsSystem
}
KeyPath : SoftwarePoliciesMicrosoftWindowsSystem
FullKeyPath : HKEY_LOCAL_MACHINESoftwarePoliciesMicrosoftWindowsSystem
Hive : LocalMachine
PolicyState : Set
Value : 45
Type : DWord
ValueName : GroupPolicyRefreshTime
HasValue : True
KeyPath : SoftwarePoliciesMicrosoftWindowsSystem
FullKeyPath : HKEY_LOCAL_MACHINESoftwarePoliciesMicrosoftWindowsSystem
Hive : LocalMachine
PolicyState : Set
Value : 15
Type : DWord
ValueName : GroupPolicyRefreshTimeOffset
HasValue : True
function Config-RefreshInterval(
$interval = 90,
$offset = 30,
$gpo = "IT Policy for Workstations"
){
Set-GPRegistryValue $gpo -Key HKLMSoftwarePoliciesMicrosoftWindowsSystem `
-ValueName GroupPolicyRefreshTime -Value $interval -Type DWord
Set-GPRegistryValue $gpo -Key HKLMSoftwarePoliciesMicrosoftWindowsSystem `
-ValueName GroupPolicyRefreshTimeOffset -Value $offset -Type DWord
}

While functional, this version of the Config-RefreshInterval function will output an object with GPO metadata properties each time it calls Set-GPRegistryValue. The script could easily be rewritten to be more intelligent about processing these objects and only displaying errors upon issues. One factor would be catching permission denied errors when a non-administrative user attempts to change such policy settings. Another improvement would be consuming this output rather than emitting it. Below is a rendering of some of the kinds of properties that these Microsoft.GroupPolicy.Gpo objects have.

DisplayName : IT Policy for Workstations
 DomainName : wernerconsulting.com
 Owner : WETRACONDomain Admins
 Id : 55b219f1-e561-4fb5-a8ff-7b79b86e028
 GpoStatus : AllSettingsEnabled
Description : 
CreationTime : 9/28/2011 8:54:40 AM
 ModificationTime : 9/29/2011 9:41:00 AM
 UserVersion : AD Version: 0, SysVol Version: 0
 ComputerVersion : AD Version: 6, SysVol Version: 6
 WmiFilter :

Note that the ModificationTime and ComputerVersion properties should be updated for each call to Set-GPRegistryValue.

Both the Config-RefreshInterval and Check-RefreshInterval could easily be modified to work with the “Group Policy Refresh Interval for Users” rather than the “Group Policy Refresh Interval for Computers” by replacing the reference to HKLM with HKCU. Or better yet, we could add another parameter and associated logic to allow configuring either or both the Computer Configuration and/or User Configuration. The names of the functions are non-optimal, and could instead be called something like Get-GPRefreshInterval and Set-GPRefreshInterval. Even without such enhancements and refinements, hopefully these serve as an example that retrieving and configuring settings with a group policy object using Windows PowerShell is a fairly straightforward endeavor.

Best wishes in all your Group Policy adventures!