DON'T REINVENT THE COW

This is a place for Systems Administrators and IT Professionals to find and share ideas, solutions and templates. If you have something that helps you solve a problem, chances are it will help someone else too. So pay it forward and send an email to TheAgreeableCow at gmail. Full mudos to you!

Wednesday 13 June 2012

Preventing Password Expirations with Custom Emails and Reports

One of the big sources of calls to the Helpdesk department is the fallout from expired passwords. Generally users will get a Windows message box at login warning about this, but I find that this basic prompt doesn't always work in practise. Firstly, by default it pops up way too early and is often more annoying for your users. Secondly, most people just tend to ignore it and often continue to do so until it is too late. Also, for environments that use Citrix published apps or terminal services sessions, there can be some delays in password replications and conflicts if users change their password at logon. This can lead to account lockouts and even more Helpdesk calls! Finally, if you happen to turn on some group policy features, this warning simply will not show up at all.

So, this project is about contacting your users via email and advising them with your own clear message that their passwords are about to expire. At the same time generate a simple report for the administrator, giving them a heads up to potential issues. The original script was sourced some time ago, so if I find the originator, I'll be sure to pass on all mudos.

Also note, that this script uses Quest's ActiveRoles. You can of course easily customise and use the native AD module. Once you're happy, set it up as a daily scheduled task. Ideally do this late in the afternoon, to remind users just before they are about to log off. Also have a look at customising the messages within the emails. You do want to keep this simple but informative. Keep in mind that since passwords can be sensitive and phishing is so easy, you don't want to establish bad behaviours (such as clicking on a hyperlink).

There are three broad sections in the script. The first is to email users whose passwords have expired. I find this a little counter intuitive, but some environments might find this handy. Perhaps they might still have Blackberry working or you might want simply want to send it as a record with information about how to avoid next time.

The second section is where it sends an email to each user whose password is expiring within your designated time. Personally I set this as less than 5 days. This is enough to cover weekend and part timers, but not so repetitive that it becomes annoying. Additionally, you might also have system accounts, so in these cases (where their isn't a valid email recipient), it will send the email to the administrator.

The final section is where it collects all of the users whose passwords are about to expire and all of the users whose passwords have expired, and wraps it up into a nice email report for the administrator. This can be handy, because you can see the people that are ignoring their emails as they just keep showing up in that report! A quick proactive phone call would be much appreciated by the user and the Helpdesk.

Here's the full script.


 Cheers,
         (__)
         (oo)  ok
   /------\/  /
  / |    ||
 *  /\---/\
    ^^   ^^


Thursday 7 June 2012

Discovering Client Connections with Lync 2010

In this post we'll discuss a number of ways to discover information about your Lync clients. One of the great things about Lync 2010 is the detailed monitoring and reporting that comes out of the box. However, one thing that is difficult to find, is comprehensive information about the growing list of clients that are connecting to your Lync servers.

So, what is a client exactly? Typically, this is going to be either a Lync enabled phone or the Lync software client running on your PC/Mac. But this could also be an Attendant console or something like a registered video conferencing endpoint. With the new Mobility functionality, this list grows dramatically with the inclusion of Blackberry, Windows Phone, iPhone/iPad and Android devices.

Why is this important? Firstly, because Lync is relatively new, there are a lot of changes and updates to the client software. By reviewing the version information of the clients connecting, you can quickly see which ones are out of date and need patching. I also find it useful to understand the uptake of certain initiatives, such as Mobility.

The Lync monitoring role does provide some insight into the client details. Amongst the number of standard reports is the IP Phone Inventory Report. This report is very detailed showing hardware, software and user activity. The only downside is that it is limited to phone agents.


Lync stores all of this information in SQL databases on the local Front End and SBA servers called RTCLocal. So, there is nothing stopping us doing a bit of querying ourselves right? Well, some people have already started doing this. Check out the neat bit of software from Stumper called Find Lync Versions. This utility does a basic SQL query to return the client connection information. It then parses the information against AD and DNS to give you a formatted table of all connected clients, usernames and computer names. For larger environments, this tool becomes a little limited because you need to run separate queries against every server in your environment that has client registrations.

After mobility was released, I wanted to keep an eye on the uptake and offer some personalised training. So it was important to see what devices were being used. At the time I could not find any easy way of reporting on this. So I asked our SQL guys to put something together that we could use to query all servers at the same time and return a list of meaning information. We then added this to the reporting services, along with the other Lync reports on our central SQL server. There is a lot of data in there, so we ended up just including filters for the Username, Server, Client Version Keyword or Client Type. The later is presented as a dropdown list, performing a fixed keyword match on the client version string.

  • Mobility               (keywords contain “RTCC/”)
  • Video Conf          (keywords contain “Polycom”)
  • Lync Client          (keywords contain “UCCAPI/”)
  • Lync Phone         (keywords contain “CPE/”)

The new report quickly allows us to do thing like "Show all users on Server 1", "Show all phones in the enterprise that are running version x", or "Show all users connecting with iPads" for example. Visibility is a wonderful thing!


Here is the base query code we used.


 Cheers,
         (__)
         (oo)  ok
   /------\/  /
  / |    ||
 *  /\---/\
    ^^   ^^



Wednesday 6 June 2012

Using multiple copy streams with Robocopy

This is a quick post to outline a technique I've used to migrate file servers using robocopy - or to be specific, lots of parallel robocopy streams.

The script works best when you have multiple 2nd level sub-directories contained in the root directory. The VBS file below parses the directory names into seperate robocopy command line statements inside a new batch file. When the batch file(s) are run, a seperate robocopy stream is processed for every sub-directory at the same time.

All of the usual robocopy command switches can be used of course. For one off jobs, these multiple parallel streams are much faster than a single stream. It's also great for syncronising file stores if run as a sheduled task.

Here is the code.


 Cheers,
         (__)
         (oo)  ok
   /------\/  /
  / |    ||
 *  /\---/\
    ^^   ^^



Tuesday 5 June 2012

Getting Unassigned Numbers in Lync 2010

So picture the scenario, you've got a new user starting tomorrow and you need to assign them a phone number. But which number? One of the complexities with any domain integrated VOIP system is keeping some sort of control over the allocation of phone numbers. You may very well have an up to date phone list, but Active Directory and Lync don't really care about your über Excel skills.

Check out Ståle Hansen's blog post for his original script that did a brilliant job solving this problem. The updated script below runs from your Windows 7 machine and presents a list of phone numbers that are either Assigned or Unassigned for your choosing.

In large enviornments covering multiple sites, this could still be a complex result set. So rather than just throwing out a list of potentially hundreds of numbers, the script compares the numbers it finds against the "Unassigned Number Range" feature in Lync. This is primarily used to play a message or redirect a call if someone accidentally calls a number that has not been assigned to anyone. Here's a Technet article with more information.

In our environment, we simply redirect these calls to reception. The ranges were setup for each site, corresponding to each contiguous block of numbers that we had been allocated by the phone company eg 1234 1200 to 1234 1299. We're not going to do any redirection with this script, just use the ranges to provide some measure of control for selecting and displaying results.


The script checks a series of phone number repositories using typical Lync shell cmdlets such as Get-CsUser and Get-CsAnalogDevice. All up this includes:
  • User numbers (including Private Number)
  • Analogue Devices
  • Common Area Phones
  • AutoAttendant numbers
  • Dial In Access Numbers
  • Trusted Application Endpoints
  • Response Groups
As the script runs it queries each range, advises how many numbers are in use and prompts for an action to either show the Unassigned Numbers, the Assigned Numbers or to skip that range and move on to the next one. 



Here is the complete code.


 Cheers,
         (__)
         (oo)  ok
   /------\/  /
  / |    ||
 *  /\---/\
    ^^   ^^



Friday 1 June 2012

Using Get-WinEvent and XML filters to query Event Viewer

In previous roles in IT support and network administration I quickly leaned the benefit of Windows Event Viewer. Fundamentally for me it served two purposes; a retrospective log where I would go and seek an answer to something that had just happened, or alternatively a proactive log where I could get a heads up on potential issues.

Proactive is always good, right? The problem is there is only so much time in the day to spend scrolling through all of that noise. There needs to be a process of filtering and reporting, which allows you to get to important information efficiently. Now, there are a number of commercial programs around that manage this already, so if your scale and budget are so inclined it's a very valid solution. Event Subscriptions are also another method of collecting logs from dispersed machines. Combined them with tasks and you've got a nice little system for gathering and alerting.

In this post however, I'm going to look at gathering event logs using powershell with the get-winevent cmdlet. More importantly, we're going to look at including an XML filter in your query to make the whole process much, much faster. Finally, I've added some code to export the logs to a CSV file or an email for reporting purposes.

The example below is a mini project to collect print server job logs as it serves as a good example of the scenario above. By default the individual user job logs are not enabled. So the first thing we need to do is turn on Print Services Operational logging via Event Viewer > Applications and Service Logs > Microsoft > Windows > Print Service > Operational > right click to Enable Log.

Hands up who loves the way you can doing something in a GUI and it produces the code for you in the background? Well, Windows Event Viewer has a neat way of doing GUI based filtering, which result in XML based queries that you can use in your coding.

Open up event Viewer and create a basic filter on an EventID through Actions > Filter Current Log. Here's an example using EventID 307 (which is a successful print job).



If you then click on the XML tab at the top, you will see the XML query string that is being used. This is what we need to copy into the get-winevent cmdlet.


In your script, the string needs to simply be defined as a variable and enclosed with an apostrophe, for example:


The second part of this process is working out what parameters are contained in the event, so you can define them as variables for manipulation in your script. So, going back to one of the events in the log simply click on the Details tab. Here you will see all of the parameters that can be retrieved in a Friendly View.


I've masked out some details in the above example,but you can easily see how it is laid out. The syntax for your script is also straight forward. Firstly a single line for the xml conversion, then simply call the parameters working through the levels of the xml tree. In this case User Data > DocumentPrinted > Parameter. For example:


So, here is the complete code for this project, including writing the output to a CSV file and attaching it (or including it as the body), to an email


 Cheers,
         (__)
         (oo)  ok
   /------\/  /
  / |    ||
 *  /\---/\
    ^^   ^^