Disable rogue domain computers with Powershell

Ever find out that there’s employee’s insist on adding computer to your company’s domain? Hate having to manually check every once in a while for new machines? Fret no more! Here’s a simple script that will simply disable the computer accounts!

#
#	disable unauthorized computers
#

## Create the AD object for looping through.
$root = New-Object DirectoryServices.DirectoryEntry "LDAP://CN=Computers,DC=domain,DC=com"

$selector = New-Object DirectoryServices.DirectorySearcher
$selector.SearchRoot = $root
@'
operatingsystemservicepack
iscriticalsystemobject
samaccountname
useraccountcontrol
primarygroupid
instancetype
displayname
pwdlastset
logoncount
samaccounttype
serviceprincipalname
dnshostname
usnchanged
lastlogon
accountexpires
adspath
distinguishedname
operatingsystem
codepage
name
whenchanged
lastlogontimestamp
operatingsystemversion
objectclass
countrycode
cn
whencreated
objectsid
objectguid
localpolicyflags
objectcategory
usncreated
ms-DS-CreatorSID
createTimeStamp
'@ | set-variable props
$selector.PropertiesToLoad.addrange($props.split([Environment]::NewLine));

##Find everything in the Computers OU
$finds = $selector.findall()

##Loop through and find Computers that were added by non-IT personel.
##Since IT usually has rights to add machines to the domain, ms-ds-creatorsid isn't populated.
foreach($c in $finds) {
	if(([string[]]$c.Properties["ms-ds-creatorsid"]) -eq $Null) { continue; }

	##alright, we've passed the test, now to disable it!
	$a = [ADSI] $c.path;
	$a.psbase.invokeset('accountdisabled', $True);
	$a.psbase.CommitChanges();
}

My intertubes are clogged!

Last week I decided to rid myself of paid television and save myself about $90/mo. For the first day it worked fine, but now my internet has been down since Thursday. I’d like to think that normally I wouldn’t be as frustrated with them as I am, but after talking with them via chat and phone and getting semi-conflicting stories I wonder.

Twitter Weekly Updates for 2009-06-24

  • Magical Sign Adventure http://bit.ly/H1WOV #
  • RT @5thWall: RT @kylefox: Interesting post about "Color and Reality" http://bit.ly/4m15I #
  • Gonna look at bikes tomorrow at Rick's Cycling! http://rickscycling.com/ Assuming a I wake up in time! #
  • #workout Yay! My arms aren't so sore anymore! #
  • Writing documentation is painful, but it can be very rewarding! #
  • Learned about msbuild and more about compiling from the command line! #
  • When troubleshooting the 0×8004010F error in outlook (exchange 2007 environment) check the firewalls on your MAPI servers! #

Powered by Twitter Tools.

Time filter: C# Project files

Here’s a clightly cleaned up and better version of my time filter project thing, businesshours.zip. Archive contains code, build batch file, and binary.

Some changes this round:

  • Takes into account timezones.
  • No longer is missing a day in it’s calculations.
  • Debugging command line argument to track the inner workings.

Should I feel like it:

  • Code cleanup
  • Delete unused variables
  • Useful comments

Time filtering: PHP version

As mentioned before, I originally wrote my time filter in PHP but converted it to C# for speed. So here it is for posterity and reference.

class nonWorkRanges {
	public $parse;
	public $start;
	public $end;

	/*
		this::start and this::end stucture

		day = 1...31
		month = 1...12 (xx = reoccurring)
		year = YYYY (xxxx = reoccurring)
		weekday = 0...6 (sunday...saturday, if this is set we ignore the day, month, and year values)
		hour = 0...23
		minute = 0...59
		second = 0...59
	*/

	public function businessTime($created, $response) {
		$start = $this->start;
		$end = $this->end;

		if(isset($this->start['weekday']) and isset($this->end['weekday'])) {
			$ticks = 0;
			$days = date('z', $response) - date('z', $created) + 1;

			$basetime = mktime(0, 0, 0, date('m',$created), date('j',$start['weekday']), date('Y',$created));

			for($dayi=0; $dayi<$days;$dayi++) {

				$day_start = mktime(0, 0, 0, date('m',$basetime), date('j', $basetime)+$dayi, date('Y',$basetime));
				$day_end = mktime(23, 59, 59, date('m',$basetime), date('j', $basetime)+$dayi, date('Y',$basetime));
				$dow = date('w', $day_start);

				if($start['weekday'] < $end['weekday'] && ($dow < $start['weekday'] || $dow > $end['weekday'])) {
					continue;
				}

				if($start['weekday'] > $end['weekday'] && ($dow > $start['weekday'] || $dow < $end['weekday'])) {
					//var_dump($start['weekday'] < $end['weekday'], ($dow > $start['weekday'] || $dow < $end['weekday']));
					continue;
				}

				$mask_start = mktime($start['hour'], $start['minute'], $start['second'], date('m',$day_start), ((date('j',$day_start)-date('w',$day_start))+$start['weekday']), date('Y',$day_start));
				$mask_end = mktime($end['hour'], $end['minute'], $end['second'], date('m',$day_start), ((date('j',$day_start)-date('w',$day_start))+$end['weekday']), date('Y',$day_start));

				for($i=0; $i<86400; $i++) {
					$loc = $day_start + $i;
					$tf = array(
						$loc < $created,
						$loc > $response,
						$loc < $mask_start,
					 	$loc > $mask_end
					);
					if((!$tf[0] && !$tf[1]) && (!$tf[2] && !$tf[3])) {
						$ticks++;
					}
				}
			}
			return $ticks;
		}
	}
}

Time filtering for helpdesks

One of the goals this year is to have an average response time of 15 minutes for all helpdesk tickets, but we have one problem, no way to track or know if we’re getting closer.

During my initial research, the only thing I could find was code that couldn’t be customized through configuration files so it would be easier for management to configure later. Since the tool we wanted to get the reports from was Eventum, I originally wrote this in PHP, but it proved way to slow and so I converted it into a C# app to handle the calculations.

Besides the code below, you’ll need masks.xml, which holds the info about business hours.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;

namespace eventum_responsetime
{
    class Program
    {
		//businesshours.exe -created "any date format DateTime can parse" -response "any date format DateTime can parse"
        static void Main(string[] args)
        {
            System.DateTime base_unixtime = new System.DateTime(1970, 1, 1, 0, 0, 0, 0);
            long int_base_unixtime = base_unixtime.Ticks / 10000000;

            if (args == null || args.Length == 0)
            {
                args = new string[] { "nothing" };
            }

            System.Collections.Hashtable hargs = new System.Collections.Hashtable();

            hargs.Add("nothing", Array.Find(args, (delegate(string s) { if (s.ToLower() == "nothing") { return true; } return false; })));

            hargs.Add("created", args[Array.FindIndex(args, (delegate(string s) { if (s.ToLower() == "-created") { return true; } return false; })) + 1]);
            hargs.Add("response", args[Array.FindIndex(args, (delegate(string s) { if (s.ToLower() == "-response") { return true; } return false; })) + 1]);

			//Load the masked times xml.
            XmlDocument xmld = new XmlDocument();
            xmld.Load("./masks.xml");

            XmlNodeList masks = xmld.GetElementsByTagName("mask");

            nonWorkRanges[] a = new nonWorkRanges[masks.Count];

            long ticks = 0;
            for(int i=0;i<a.Length;i++) {
                XmlNode n = masks[i];

				//Load up the masks
                a[i] = new nonWorkRanges();
                a[i].start.weekday = (n["start"].Attributes["weekday"] == null) ? 0 : int.Parse(n["start"].Attributes["weekday"].Value);
                a[i].start.hour = (n["start"].Attributes["hour"]==null)? 0 : int.Parse(n["start"].Attributes["hour"].Value);
                a[i].start.minute = (n["start"].Attributes["minute"]== null) ? 0 : int.Parse(n["start"].Attributes["minute"].Value);
                a[i].start.second = (n["start"].Attributes["second"] == null) ? 0 : int.Parse(n["start"].Attributes["second"].Value);

                a[i].end.weekday = (n["end"].Attributes["weekday"] == null) ? 0 : int.Parse(n["end"].Attributes["weekday"].Value);
                a[i].end.hour = (n["end"].Attributes["hour"] == null) ? 0 : int.Parse(n["end"].Attributes["hour"].Value);
                a[i].end.minute = (n["end"].Attributes["minute"] == null) ? 0 : int.Parse(n["end"].Attributes["minute"].Value);
                a[i].end.second = (n["end"].Attributes["second"] == null) ? 0 : int.Parse(n["end"].Attributes["second"].Value);

                ticks += a[i].ticks(DateTime.Parse(hargs["created"].ToString()), DateTime.Parse(hargs["response"].ToString()));
            }

			//Output how much business time elapsed.
            Console.WriteLine(ticks.ToString());
        }
    }

    abstract class mask {
        public int weekday;
        public int hour;
        public int minute;
        public int second;

        public DateTime time;
    }

    class startMask : mask
    {

    }

    class endMask : mask
    {

    }

    class nonWorkRanges
    {
        public startMask start;
        public endMask end;

        public nonWorkRanges()
        {
            this.start = new startMask();
            this.end = new endMask();
        }

        public long ticks(DateTime created, DateTime response)
        {
            if (start.weekday != null && end.weekday != null)
            {
                long ticks = 0;

                int days = (response - created).Days + 1;

                DateTime basetime = new DateTime(created.Year, created.Month, created.Day, 0, 0, 0);

                for (int dayi = 0; dayi < days; dayi++)
                {
                    DateTime day_start = new DateTime(basetime.Year, basetime.Month, basetime.Day, 0, 0, 0);
                    day_start.AddDays(dayi);
                    DateTime day_end = new DateTime(basetime.Year, basetime.Month, basetime.Day, 23, 59, 59);
                    day_end.AddDays(dayi);

                    int dow = (int)(day_start.DayOfWeek);

                    if (start.weekday < end.weekday && (dow < start.weekday || dow > end.weekday))
                    {
                        continue;
                    }
                    if (start.weekday > end.weekday && (dow > start.weekday || dow < end.weekday))
                    {
                        continue;
                    }

                    DateTime mask_start = new DateTime(day_start.Year, day_start.Month, day_start.Day, start.hour, start.minute, start.second);
                    mask_start = mask_start.AddDays(-dow).AddDays(start.weekday);

                    DateTime mask_end = new DateTime(day_start.Year, day_start.Month, day_start.Day, end.hour, end.minute, end.second);
                    mask_end = mask_end.AddDays(-dow).AddDays(end.weekday);

                    for (int i = 0; i < 86400; i++)
                    {
                        DateTime loc = day_start.AddSeconds(i);

						//Simply to make reading the if block easier.
                        bool[] tf = new bool[] {
                            loc < created,
                            loc > response,
                            loc < mask_start,
                            loc > mask_end
                        };

                        if((!tf[0] && !tf[1]) && (!tf[2] && !tf[3]))
                        {
                            ticks++;
                        }
                    }
                }
                return ticks;
            }
            return 0;
        }
    }
}

Another notch in the belt

One more trip around the sun completed! So what’s happened this time around?

*Highlight

New design? More like upgrade!

Last Thursday I upgraded the software for my site and it broke everything. So now I’m in the process of getting things back to the way they were…maybe. Katrina’s talked about wanting to do a design or background for my site so it may have some influence on what I do.

In the mean time, enjoy this Halo 3 montage that has some awesome editing.

Twitter Weekly Updates for 2009-06-15

  • Going offline for a few days. Goodbye Intertubes! #
  • Back to the drawing board. *sigh* #
  • Dairy Days FTW! #
  • RT @parenteau: RT @riotpixel: Brilliant & detailed shadow art. Created by British artists Tim Noble & Sue Webster http://tr.im/o9R9 #
  • Yeah, don't ever do this with PHP…unless your server is very high-end http://pastebin.com/m9a5b1dd #
  • Purple Trim FTW! #
  • THE DARTH SIDE: MEMOIRS OF A MONSTER http://darthside.blogspot.com/ #
  • The first portable computer that will melt your face off! http://bit.ly/MyeSA (thanks acidus!) #
  • RT @5thWall: I guess there are worse things you could do if you're bored and have a bunch of sheep. http://bit.ly/ihp8 /ali (via @waitwait) #
  • Thanks @Jayman9 I'll take a look at 'em! #
  • It's Monday…and yet I've been WAY more productive than usual….weird. Must be motivated or something. #
  • RT @DreamInCode: Tutorial: Unit Testing With C# and NUnit: http://www.dreamincode.net/forums/showtopic108751.htm #
  • I think I may need to learn about ASP.NET for business purposes. Any recommended tutorials or resources? #

Powered by Twitter Tools.

Twitter Weekly Updates for 2009-06-06

  • 6 MINUTES UNTIL THE WEEKEND! #
  • 8 MINUTES UNTIL THE WEEKEND! #
  • RT @shaycarl: Do you want more Subscribers on You Tube? Then you HAVE to check this out! http://bit.ly/gkNnw #
  • Project Natal, Probably the most awesome Xbox peripheral to date. http://bit.ly/O6imW #
  • hmm, have a login script compile an exe and run it? it may have some potential. #
  • Memories of the radio station are coming flooding back! :O #
  • Coke (Coca-cola) Babies http://bit.ly/qEWNF #
  • HL2 fan film http://bit.ly/W2aCA #
  • whooo! late night shenanigans at work! fixing what should never have been broken…or was broken since before it began! #
  • What a roller coaster day. I’d say never again, but tomorrow will probably be the same. :/ #
  • Pretty sure I’ve said it before, but I <3 stored procedures! #
  • To bend to the rules or stand in defiance of them? I’m leaning towards defiance. #
  • wee! picking up a complicated project midway through! FTL! #
  • Blast from the past! http://bit.ly/1gMoN #
  • disregard last tweet, turned out I’m blind to quotation marks. #
  • Anyone know why I get an “object expected” error when trying to do <input onclick=”func()” /> in IE? #
  • awesome! #msdn example code won’t even run! :@ #
  • Hmm, you can do CRM customizations with JScript….hmm #

Powered by Twitter Tools.