I have an addiction problem

At first I thought I had a drinking problem. As evidence by the picture below, I drink A LOT of coffee!

That's a lot of stoppers!

Then as I’m driving in to work I’m listening to NPR. They are talking about the health rankings for Kansas, apparently it’s an annual report of the state of the health system for a given state. As I’m listening to this I find myself thinking, where did they pull their data from? I wonder if I could get at that data? I could easily write a Management Pack to monitor….holy crap!

Yes, I found myself roughing out how I would write a Management Pack in Operations Manager to report on the state of the health system.

Hello, my name is Jeff. I see the world in varying states of health Green (Happy), Yellow (Unhappy) and Red (Angry).

Week In Review : 07/27/2014

Another week coding the app, the nice thing is that the MVC re-write is pretty much done. In fact the idea of utilizing the DB to store information is actually in place, something I wound up having to do. I have decided to store a snapshot of the relevant data in some tables at login. The actual collection of data and table insert takes roughly 20 seconds, so it’s pretty quick. This speeds up everything quite a bit, the entire site feels a lot more responsive.

I’m also having to cron an insert for the proteus data every 24 hours. There isn’t a simple way of to query the underlying properties of a given ip4Network, so I’m just going to collect them all. There are roughly 4,000 ip4Networks defined and it takes about 2 minutes to enum each one and write the underlying properties to a table. Since that data is much more static than the VMWare data, 24 hours on insert is sufficient.

I’m currently making much better use of my classes, and passing data back and forth between views with them. On two of them I have over-ridden the ToString() method so that I can just class.ToString() to get my confirmation email, it looks really slick in code. The added benefit of what how I’m doing this now is that I only store the friendly names in the class, so displaying the information back out is super simple. Then just a couple of simple queries to return the information I need.

I have tweaked a few things on some of the projects that are used.

  • I have written a slightly better way of getting to the cloned network adapter than what I was doing in the past.
  • A lot of my custom validation code has slimmed down, since for these I return a bool, I don’t need to define an object to hold the result and check that, I simply check the call.

As the rest of the code is already done, I figure I have a couple more days then we can call it done. The only major thing left for me is to build the method to create a new virtual machine, and the little I’ve looked into it, it appears it’s nearly identical to how you clone a vm.

See you next week, if not sooner!

Week In Review : 07/20/2014

I had intended these to be weekly, and I got off track, sorry about that. So I missed the week of Jun 29, Jul 6 and Jul 13. I can tell you that the week of the 29th ended on July 5th, and I was pretty wiped out from all the fireworks and stuff. The week of the 6th we were in Florida on vacation and the last couple of weeks (Jul 13 and this week Jul 20) were about the same.

This week has been all about the code. My boss asked me to focus on getting the revised provisioning web app up and running, so I’m happy to report that it is on par with the previous version. The previous version was just a basic web app, nothing fancy, it had some pages that worked like a form and it was all driven by click events and such. It worked really well, but it lacked flexibility.

See, everything was written on a single page, the various “pages” were in reality Asp Panels separated by div’s. In order to add a feature I would have to figure out where to place it, then adjust all the code to handle it. Some of that was problem, I should have broken things out more earlier into separate functions, that may have made it easier, but I doubt it.

The new version is using MVC, each page has a model on the back to represent the data. So each page is strongly typed, For most things I use the built-in validation provided to me from that, for a few things I wrote some custom validation, for example to make sure someone chooses a valid option from a drop down and not the text “–Select an item–”. There are a few places where the custom validation just wasn’t appropriate. So I was able to create a couple of functions to handle that, I must say that in this new format it is a lot easier to work.

The way I have it now I just pass around the models from one page to the next, updating as we click along. I can pass those models to my custom validation and return a simple error message quite easily. Displaying the validation error’s previously was a pain, so I really enjoy the way this works.

Another nice feature is I can re-use a lot of what I do so I can provide new features. For example, I want to provide a way for admins to create a bare VM. I can use all the models I already have, as well as just about all the logic behind how that is wired up. If I want to add a new feature it’s as simple as writing up a model and then building a page for it, then writing a controller to handle it all, or updating an existing controller.

Some thoughts I’m having for the next version is to use the database, currently I’m not doing that at all, I’m actually querying VMware directly, this introduces some lag that the previous version didn’t have. I think that some of that can be resolved by me working through my code to get it optimized, but a lot of that is just inherent in how it all works.

So the thought was a separate job that would at regular intervals poll VMware for clusters, datastores, vm’s and so forth. Then the app becomes almost instantaneous, since instead of asking VMware we’ll ask the database. Then before we provision we will validate everything against VMware, which may introduce some entertaining issues, but as our change process is fairly slow I think this will work nicely.

The nice thing about storing this data I can add tables to give me logic that I had to code for before. I will be able to access some data without calling VMware since it will be stored in the database and some of the code I wrote to pull data from VMware I can dump as it won’t be needed.

So what all code am I using?

mod-VMware : allows users to connect to, query and clone (soon create) virtual machines
mod-proteus : allows users to connect to, query and add host records to Proteus and retrieve IP information for new hosts
mod-servicenow : allows users to connect to, query and create service tickets and configuration items
mod-Zenoss : allows users to connect to, query and add devices to Zenoss monitoring
mod-ads : allows users to connect to, query and create objects in Active Directory

I feel that I’m getting closer to my idea of being modular, where we can plug in the various things we want. I still haven’t worked that out yet, but in my head it works ;-)

enjoy!

Week In Review : 06-22-2014

Not a terribly eventful week, I’ve been working on tuning Ops down and clearing out the errors, and lowering the signal to noise ratio. One of the hardest ones has been the domain trust monitor in the AD MP. So we use the firewall to isolate VLAN’s from one another and I don’t know that I totally agree with that, but one thing at a time I suppose. Our DC’s couldn’t resolve another domain to which we have a trust established, you read that right. So, I tried several different requests to make that go. I created their zone as a secondary in my DNS, had to allow TCP/UDP 53 through for that to work, still no go. Then I noticed that LDAP was being dropped on one of the firewalls so had to allow that through, still no go. Finally took out the big hammer and had those DC’s added to the same firewall group as mine. That worked, sort of, yesterday I noticed I’m still getting some errors, so I’ve decided that Monday I’m going to work on trying to get that and as much of everything else sorted out as I can.

I did get some code written this week, I have a proof of concept wired up that will allow us to copy profile information from one system over to SharePoint Online. I would feel better about it if we weren’t forced to use a deprecated web service. Which I need to bring up in our next meeting about this. The other code I worked on was the Arin Whois-RWS interface. I didn’t realize this, but Arin has a REST interface that allows you to query their Whois database.

So I’ve been working on that and wrote up a very nice little piece of code that is suitably generic for me, which I like!

So, if I want to start using the .net HTTP stuff on the Windows Phone and tablets, it looks like I have start using the async stuff. Also, I think a lot of their HTTP request stuff is moving to that anyway, so I’ll really need to keep that in mind as I progress in code writing. At any rate, I really like this GetResource function. A lot of the code I write I try to make as reusable as possible, I hate having to write code that more or less does something another piece of code already does. So we send in a string URL and cast it against the XML classes we created to return objects that we can easily work with. The disappointing part of this for me was I should be able to pass as part of the request that I want a JSON response, but the server seemed to ignore my ContentType request and kept spitting back XML.

As I was working through this I started thinking about the other code that I’ve written for VMware, Hyper-V, ServiceNow and so on. I think I’m going to re-write my provisioning web app so that I can be a little more pluggable than I currently am. For the VMware stuff I think this will be easier as I’ve already re-written that code to use the ManagedObjectReference for everything, and since at it’s root, that’s just a string this may be pretty simple. I’ll just need to create a couple of simple interfaces that I can pass strings or arrays into, as well as some functions to take the VMware objects and pass them up as strings or arrays.

Also I got notified from Microsoft that they are doing away with domains.live.com and that if you use that service for mail and so on, it will stop working very soon. So, I decided I would not wait around and moved my wife and daughter over to my Office365 subscription getting their email to work was simple, but my account to forward to the patton-tech.com one…not so much. Hopefully I can figure this out, because just adding that address to my account was not an option.

Week In Review : 06-15-2014

It’s time for another exciting edition of WIR! This week was filled with updates! Rolled updates to our Domain Controllers and one of them took nearly two hours to come back from a reboot! Normally not a big deal, but when your 30mi away…a little stressful! I also rebuilt my work laptop this week, earlier this year I had done something stupid with an external drive and wound up with Windows installed on Partition 2, on a disk with just one partition! Needless to say, rebooting my laptop didn’t happen all that often at all!

Speaking of Active Directory Domains, we are moving ever closer to having just one domain on campus. The internal private Edwards domain went away this week! It’s always just a little nerve wracking when running through dcpromo to remove stuff, but it went well. Didn’t appear to leave any unsightly meta data floating around AD!

Also spent a fair amount of time talking with the guys at Edwards to go over how they image machines. They routinely call us to have a workstation DNS entry removed, and needless to say it’s a little annoying. They ought to be able to do this themselves, but since it’s not their DNS they don’t have rights. Not to mention they way they do their image is a little different.

This is how it goes, a user is up for a new computer. In an effort to minimize the inconvenience this can sometimes to be, they image the new computer, load their software, and finally join it to the domain. This last part is what gets them, they tack on a “-1″ to the new workstation name. Normally not a big deal, but the last part is where it gets hairy.

The new workstation is delivered to the user, the old workstation is unjoined from the domain, the new computer is renamed to the old computer name…and boom. Sometimes this works (they say) but I can’t imagine how. So, the first comment was hey, how about using service tags, or mac addresses to identify these machines uniquely, then you will never get hit with this issue. Nope, they like usernames as computernames, it makes it easy to correlate user to workstation. Apparently it’s too difficult to track that down in SCCM? Not likely, but oh well.

So, what to do, well we could just have them call every time, but that’s a hassle, not to mention there’s no code involved! My solution, create an Orchestrator runbook, that is provided a computername. With that information it scrubs AD and removes the DNS entry as well. This Runbook would run in the context of a service account that has rights to do this. They would simply login to it with their admin account, we would use their group information to verify that the computer they want removed lives in their OU and then remove it and the DNS entry. If it doesn’t live in their OU it fails. Sounds elegant to me ;)

A final solution, which will take much longer to implement, will be an appliance from BlueCat that sits between AD DNS and Proteus DNS. This appliance will use the Proteus web service and the MS RPC to translate information between AD and DNS. This will get us to a very similar place as my Runbook idea, but the one advantage is this will also get us to a place where we can pull our AD DNS out of the public facing DNS, effectively hiding thousands of servers and workstations.

Another fun one that happened, you can’t push the ops client to a Domain Controller using SCCM Client Push. If someone tells you they can, they are lying to your face! I’m going to write up a post, but the short of it is, Client Push relies on a local administrator to work, how do you do that on a Domain Controller?

OH! I also polished off my SQL PowerShell, so I’ll write about that as well. It works pretty well, created some new functions to let me more accurately find SQL Instances, still don’t have a good way to talk to the WID but it’s kicking around in the back of my head.

I also broke Active Directory Certificate Services..see you next week!

Oh, I suppose we should talk about that? So, I’ve been slowly pulling servers out of the old Ops servers and bringing them over to the new. Doing pretty well, 230+ servers in the new and growing, and under 50 in the old. The Domain Controllers got pulled in this week as well as the Certificate servers.

So, I’m working through the alerts, tuning Ops so I only hear what I need to. So, I started getting alerts about ADCS (Active Directory Certificate Services) and started working on that issue. I was seeing errors about the CRL Distribution Point being offline.

As part of the troubleshooting I had already decided to stand up a vhost to hold CRL’s among other things. So I reconfigured the CA to use that, after restarting the service as prompted by Windows, Certificate Services failed to start. The net result here was that the CRL’s were out of date and just needed to be published and then copied to the web location.

The only bit left here is to automate both the publishing and the copying of the files over to the web server. Of course this seems well suited to creating a PowerShell solution, check back later for that!

See you next week!

Week In Review : 06/08/2014

Still a lot of programming this week, but like I said before I think anymore that is more the norm than not. We did some interesting Active Directory stuff this week. We had a handful of servers get their AD objects deleted at some point, and we found out about the beginning of this week. Now my guess is these were deleted close to about 3mo ago, and they either rebooted recently or attempted to change their password recently.

About a year or more ago we changed our audit policy and started using Advanced Auditing. We were concerned about user account and group account management, but it turns out we should also have put in computer account management as well. When a computer object is deleted event 4743 is logged in the security log of the domain controller. We searched and couldn’t find that entry anywhere, when I started researching that event is when I found you need to tick the boxes for computer management.

Along those lines we had a similar issue, our admin accounts in our QA domain were disabled, since we do very little auditing at all in there, I enabled the same features so we can see when that happens. When a user account is disabled event 4725 is logged. To go along with both of these events I’m going to update our reporting in Ops on things like this.

While doing all this I found a very nice support article listing our the various event id’s and what they mean.

All of the servers that are supposed to report in to System Center Advisor, are now doing so. I feel rather stupid about the issue originally. So my first problem is that I wasn’t patched up to where I needed to be in order to even use the preview, so that was step 1. The next part is where it gets a little fuzzy, I don’t actually recall patching the clients on any of the agents reporting in, yet all 3 domain controllers reported an update agent. Coincidentally all 3 domain controllers were the only servers showing up. After some investigating with the SCA guys from Microsoft they quickly realized I had not patched my agents. So, I must have patched the DC’s, I just don’t recall doing it, hence the stupid.

So the result of this is a working program in SCCM that will patch outdated clients, which is good as my next step in this whole saga is to patch production. It’s either patch, or move over to R2 and currently I’m leaning towards patching. So currently in QA when a server gets discovered the ops client gets pushed down to them, now it will also get patched. Then the only manual part of this process left is to add them to the advisor management pack.

It’s been lots of fun talking with these guys about stuff, I’ve been invited to participate in an SCA board to go over new features and talk about how things work. My recent experiences dealing with some of the internal folks with Microsoft really make me want to work there more.

I’ve done some fun things with PowerShell this week. A new SQL module has been fleshed out and validated against just about all instances of SQL. I’m still having a hard time working with a connectionstring for the Windows Internal Database, but it will come. I’ll most likely write about this module after I’m done with this WIR.

I’ve updated the Orchestrator module. The Start-scoRunboook function worked incredibly well if you only ever had one parameter, as soon as you throw more than one it freaks out. How I originally handled it was dumb, so now the function accepts requires a hashtable object, it then compares the key (property name) field against what the Parameter object returns. This worked out extremely well, again probably a topic for a whole blog post as well.

One last pure PowerShell item is a function that writes functions. It’s not too terribly complicated and I *WILL* post about this later, but basically the idea is that Orchestrator contains Runbooks that perform some action, my module reads those Runbooks in, gets their parameters and allows you the admin to run them. What if we could have a function that would build cmdlets based on that information on the fly…

SharePoint Online! How much fun is it working with UserProfiles in SPO? Well, let me tell you, in order to do anything meaningful it appears you have to access a 10yr old web service that must be ripe for deprecation but has been forgotten about! I’d really like to get some more information direct from Microsoft about that. At any rate, I’ve got some POC code that will allow me to programmatically populate a SharePoint user’s profile with information that we glean from another source. The next step down this rabbit hole is using a 7yr old SDK (Office Server 2007) to see if I can create UserProfile subtypes! I’ve got some examples of how this works, but I’ve not written anything up yet to see if it will go, fun times ahead!

Keeping in line with the SharePoint Online topic, creating admin cloud accounts. So we have an Azure subscription that allows us to get into Azure AD for our tenant, which isn’t anything special. If you have an Office365 subscription, you can create an Azure account, hook the two together and boom…Azure AD! So I created an admin account for me, and one of the other guys on the project. After that I enabled the Multi-Factor Authentication on these two accounts. Now, when I login with my admin account, I receive a txt message with a verification code. So we have looked at this as THE way to secure access to these accounts as we begin to think about the cloud.

With that out of the way, I can talk about the Orchestration. I’ve created a Runbook that will connect to our tenant and provision a user. This came out of the Provisioning project for the larger SPO project. This code takes a single parameter, samaccountname, and then provisions that user in o365 with the appropriate licensing. There are two differences between an o365 user and a cloud admin. The first is licensing, a cloud admin gets none by default (our design), second the all important UPN, user@tenant.onmicrosoft.com. The idea is these accounts live solely in the cloud, and are used specifically for administering cloud things. I have a couple modification in mind, first I need to populate the AlternateAddresses field, as well as the MobilePhone field. Then I need to see if I can enable MFA in Azure for these accounts automatically.

Lots of Orchestrator this week, but now that I’m ready and the network is ready it’s time to start working on Orchestrating Windows Updates. I’ve started a rough draft of that at the moment:

  1. basically get a list of servers (or service)
  2. for each server start maintenance mode (ops and Zenoss)
  3. get the applicable updates (SCCM perhaps)
  4. apply the updates
  5. reboot if needed
  6. make sure the server is back online
  7. check if required services are running
  8. leave maintenance mode
  9. and move on to the next server

If one server in a group fails then we need to stop the update process and throw an alert in ops and Zenoss. This will prevent an entire service from going offline if the updates cause an issue.

Week In Review : 06/01/2014

Another very productive week! Spent a lot of time on Operations Manager, and getting the Low-Privilege SQL Monitoring to work. There appears to be a problem with how the MP calculates PLE and is using data and advice that is now about 10yrs old, so I disabled that monitor.

We have about 20 SQL servers that are directly under our control, so trying to get those setup manually would have been painful. So I worked up a nice little SQL PowerShell module for automating some of that for me. Considering the number of servers in total we have, that code is really going to help out.

I didn’t spend all my time in Ops though, I did do a lot of Orchestrator this week. It’s been so nice having the network setup in such a way as to make this all so easy now. There are still some kinks that I need to work out, but otherwise it’s been really fun. One of things I did this week for Orchestrator was build a PowerShell module for it as well. I talked about that one Posted in IT, Orchestrator, Projects, Windows PowerShell, WIR

System Center Orchestrator PowerShell Module

This is one I’ve had on the back burner for a while, so yesterday morning I roughed up the basic framework for a PowerShell module. I have a few Runbooks at work, that it would be super cool to just run from PowerShell, and since lately I’ve been all up in the web services this was as good a time as any.

The Get cmdlets were all pretty simple, in fact there is really only one that does any real work Get-scoWebFeed. I probably could have used Invoke-WebService, but that’s no fun so I used .Net to make my own, and it’s really pretty simple. I just go ask the Orchestrator server (on a specially crafted url) to spit out the xml, then I just return it.

The individual functions for getting Runbooks, Jobs and Activities handle building the special URL,which isn’t really special as much as it is specific.

The Start-Runbook was the most complicated, I actually borrowed some code from MSDN, and another guys blog (Part 1, Part 2) to build mine. Turns out some of the xml you have to build to send up has to go in a certain way. I need to adjust my code to handle Runbooks with Parameters, but right now it’s good for what I need it do.

You can find the up to the minute code on GitHub, or you can find it in the TechNet Gallery.

Week In Review : 05/25/2014

Well it’s been forever since I’ve written anything interesting so now is as good a time as any. Recently we were informed we needed to start keeping track of time spent on projects and since this is something I did for a couple of years at the School of Engineering, it’s not too difficult for me to get back into the swing. Although this go around I went with more of a journal style, not sure I like it but we’ll see.

LOTS of programming this week. I wrote a virtual machine provisioning app a while ago, and while functional I’m not sure how many folks actually use it. But there has been some renewed interest lately, mainly around removing a lot of the paperwork involved. So I’ve gotten to get my hands dirty playing around with various web services.

While not terribly fleshed out right now what I’ve got works for what we need.

  • I can communicate with VMware to provision a server
  • I can send the vlan information over to Proteus (Bluecat) to ask for the next available IP in the network
  • I can submit the details of the server, ram, cpu, disk, network information over to ServiceNOW for inventory
  • I can automatically generate tickets for handling backups and Zenoss monitoring
  • I can also talk direct to Zenoss to get the server into the system

I find more and more that programming is becoming more important for administering servers than perhaps it once was, or I’m just going off the deep-end with programming ;-)

Here are the projects on GitHub associated with i’m working on now

You will note that I have a hyper-v module, but I’ve not talked about doing hyper-v at work. We actually have a little test cluster that we spun up earlier this month to start kicking the tires.

I’ve also been talking a lot with Microsoft. We’re working through an issue where provisioning users for Lync sometimes fails. It’s incredibly intermittent and next to impossible to reproduce. I’ve taken to having the guys turning on PowerShell logging (start-transcript) before they do anything just in case they catch it so we can pass that on to Microsoft.

Spent a few hours talking with one of their SQL support guys and now when an error occurs during provisioning, in addition to sending the error out to file; I also run a query that grabs data from one of the system tables regarding communication.

What else…System Center Advisor preview is AWESOME! I’ve been talking with a program manager at Microsoft as well as one or two guys who develop it about some feedback I had given and some issues I was having. Gotta say that’s been super fun, would so love to work there!

Oh! Finally got the monitoring VLAN all setup and started moving my servers into it. Had some fun issues there, first I couldn’t get to DNS so no name resolution, no accessing servers by names…fun times! Then, I forgot to file the change paperwork for changing the IP addresses of the servers, so the firewall rules never got updated…sigh

I’ve spent a fair amount of time getting Operations Manager all happy and cleaning up the various Management Pack issues that I’ve not dealt with since I’ve not been able to communicate with the servers. One of the more challenging parts for me lately has been getting the Low Privilege SQL monitoring working, I think I’ve got it all worked out now though so we’ll see how that goes next week.

In addition to being able to access the servers from the monitoring VLAN it also appears we have just about the same level of access from our desktops! No more RDP’ing into a dozen servers to do something like tweak a registry setting or stop a service!

Oh well, that’s it for this past week. I hope to start doing some more writing but I’ve decided to at least do these Week In Review posts.

Showing off some DSC Resources

Yesterday I wrote three articles ( Part 1, Part 2, Part 3 ) about Desired State Configuration. I thought I would post a slightly more complex Configuration. This configuration performs several actions on the target node.

  1. Install the Web-Server feature
  2. Install several additional features that depend on the Web-Server
  3. Install the WebDeploy application
  4. Configure Windows Firewall to allow WebDeploy traffic

This particular Configuration has some nice features to note. The first of which are the parameters. You must provide a ComputerName (or guid) and a path to the WebDeploy MSI. You can also optionally specify a source path for the features, this is useful if you have cloned a server.

You will also notice that nearly all the Resources use the DependsOn property. Since all the features are web server related, I set the DependsOn property to be the WebServerRole. If you look in the documentation I believe that Microsoft has this down as Requires, but I believe it’s changed since the docs came out.

The Package Resource installs WebDeploy. The ProductID I was able to pull from the MSI using ORCA ( SDK Download ). If you don’t have that installed, or don’t want to install it, you can install WebDeploy on a reference machine and ought to be able to query the ProductID from WMI.

The Script Resource was a little more difficult for me, and thankfully I found a wonderful article that did the deep diving. Basically a Script has three scripts that need to run. The TestScript must evaluate to True or False. If the TestScript == False then the SetScript runs. The GetScript must return a HashTable, and the only thing that it needs to return is the Result property, but you can also specify the contents of the GetScript, TestScript and SetScript scripts. Finally the SetScript is the script that will do the thing you need done. In this example create a firewall rule to allow port 8172.

So basically what happens is when you run Start-DSCConfiguration, the script will perform a test. If that test returns true then we can assume that the thing we need done is done. If that test returns false then we need to do the thing, whatever that thing is.

When you run Get-DSCConfiguration, the script will get the state of what we did, which is why all we need is a result.