Skip navigation

Monthly Archives: October 2011

So I ran into a rather straight forward script request recently that turned into a ton of research for what is a very simple solution in the end. I needed to disable anonymous FTP on multiple XP machines. Now normally this wouldn’t have been an issue except that they are using version 5.1 of IIS.

Why is that a problem?

Well it wasn’t until IIS version 6.0 that WMI components were added.  Generally finding support information for these types of tasks can be the lion share of the work anyway, and in this case; that was most certainly the outcome.

In the end I found a comprehensive list of IIS metabase properties (the original list read as if they were only accessible via WMI which I found later to be untrue) and I was free to begin exploring them all individually and building some very simple scripts to modify our server properties.

First, lets disable anonymous FTP since that’s what started us on this:

Set oFtpServer = GetObject("IIS://localhost/MSFtpsvc")
	oFtpServer.Put "AllowAnonymous", 0 
	oFtpServer.SetInfo

 

Now for our VDs I’d like to disable anonymous while utilizing the integrated windows authentication instead.

Set oWebServer = GetObject("IIS://localhost/W3SVC")
	owebserver.put "authflags", 4
	owebserver.setinfo

 

Simple enough, instantiate the object, put a property change in, then commit the change.  In these examples I’m setting the changes at the root, but it’s possible to drill them down to specific VDs by finishing the full path when instantiating.

Thankfully technet saved my behind after some digging, but here’s the list of Metabase Properties for anyone reading this who might find themselves at a point of frustration over dealing with legacy IIS installs.

Be sure to also familiarize yourself with the data types etc if this is new to you.

Alright, so I received a pretty loaded technical topic from my good friend Matthew.  Mind you I asked for a technical topic to write about, and he did provide one but the question was:

What is an API and why/when would you use one?

Now seeing as how I already stated that is a loaded question, it deserves a bit of programming fundamentals.  I promise to keep this high level, but with enough detail that a novice programmer could glean a bit of workable information from it.

First I want to explain some basic program flow and design (paradigms).  I’m going to provide some very basic examples of procedural programming and object oriented programming using php (high level).  Lets begin with a very basic example of procedural code.

Put simply procedural programming is just building things to run in a sequence but dividing it up into functions or subroutines.  I’ve demonstrated examples of this in previous posts, but here’s a simple example:


<?php
	example("functions");
	echo '<br />';
	endthis("example");

function example($arg)
{
	echo "This is a very simple example of $arg";
}

function endthis($arg)
{
	echo "This is the end of our $arg";
}
?>

Ok, so what do we have here?

We have a prescribed run order, with a fixed goal in mind.  We are calling the function example with the argument string “functions”, echoing a break, then calling the function endthis with the string argument “example”. 

Simple enough, now why is this important?

Well it’s important to see the way I am passing arguments INTO the function in order for it to produce an output.

Now in more complex applications the best thing to do is to break apart your code and build it into objects (a collection of functions and variables) that perform like tasks and tie them together.  This is object oriented programming.

Lets just take a quick look at a sample object and how it works (stick with me, this is will become relevant to APIs I promise):


<?php
	$object = New SaySomething;
	
$object->set_words("jimmy crack corn and I don't care");

echo $object->get_words();

class SaySomething {
	var $words;
		
		function set_words($new_name) {
			$this->words = $new_name;
		}
		
		function get_words() {
			return $this->words;
		}
}
?>

Ok, we instantiated the object we created, passed a string to it, then retrieved the sting.

Think of it like this, we have a program, we are loading it.  Once we have that program loaded we can begin to tell it what to do.  You can have as many instances of this object or other objects as your memory can handle. 

This paradigm affords us a massive amount of flexibility by giving us a standalone object for completing multiple like tasks.  It’s also easily extensible, allowing us to create child objects that inherit the functionality of their parent without having to modify the parent.  That will allow us over time to build a framework so to speak that we could use to quickly develop new applications on.

So, what does this all have to do with an API?

Looking at how the OOP paradigm communicates with each individual part, instantiating and then passing and receiving content.  An API isn’t much different than that.  The API simply exposes an application for communication.  It allows for interoperability from one application to another by passing messages to each other.

An example of common social networking APIs allow you to call for user information, as well as passing user information back.  Let’s use Twitter for an example. 

I want to post something to twitter, but from a custom application I’ve made.  I need a way to pass that information from my application to twitter.  The API is the interface point to allow that communication.  In a sense, twitter becomes my applications twitter object by virtue of calling and using the API (there are some stark differences, but generally this is a true statement).

The difference is, using the API doesn’t require intimate knowledge of what is going on behind the scenes.  I won’t be modifying anything within the application.  I’m simply sending and receiving information through the API.  The same is true for building an API, less is often more.  As you can imagine exposing your applications to external input and output can be a dangerous game; but that’s a much larger subject. 

The general take a way here is that although the application may consist of multiple functions and/or objects the API simply allows you to interlink one or more applications via messages.

A friend of mine Tom Miller put it rather well in a conversation we had over the subject.  “An API is a lot like a remote control”

I want the TV to change channels, I pick up the remote, press the channel up button, and the channel changes.  The remote IS the API.  My hand is the program communicating to it, and the TV is the program receiving the signal.  At no point do I need to understand how the remote works, or how the TV changed it’s channel. 

Ok, so when/why would I use an API?

That’s generally a design thing, but in most cases when you are building a platform or an application you want to improve it’s usability and not limit it.  Extensibility is the name of the game, so it makes sense to make something that would allow users to integrate other things with your application.

It’s good design because it achieves two major things towards (what I would consider) application design success.

1) It opens your platform up to the imagination of it’s user which can produce some really neat things.

2) It creates an operating environment for users with applications that depend on your platform which increases usage.

Hopefully this hasn’t left you completely confused, but like I said, it was a loaded question.

 

yea, I am that guy

Ok, so as I stated at the tail end of my last post, here’s your PowerShell to export data from Active Directory to a MSSQL Database.  This code can be easily modified to pull whatever AD info you want and to insert it.  I make use of the System.Data.SqlClient namespace, so it’s worth mentioning that you can also use MySql.Data.MySqlClient or System.Data.OracleClient for your needs.  You can examine what I’m using via the SqlClient namespace and easily correlate it back to your respective need.

 


<#
Script: AD to DB
Author: Daniel Belcher
#>
#$ErrorActionPreference = "silentlycontinue"
$CHECK = Get-Module ActiveDirectory
IF(!$CHECK) {
	Write-Host -ForegroundColor Red `
	"Can't find the ActiveDirectory module, please insure it's installed.`n"
	Break}
ELSE {Import-Module ActiveDirectory}

#\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
<#Variable String values for customizing
	the DB and to write to and OU to lookup against
		as well as the time range in days#>
<#DataBase Name:#>
$DB = "Data"
<#SQL Server Name:#>
$SQLSRVR = "localhost\sqlexpress"
<#Table to Create:#>
$TABLE = "ADExport"	
<#Days old based on activity according to passwordlastset:#>
$DAYS = 180
<#Root OU to Search:#>
$ORGUNIT = "Root OU to Search"
<#Table Create String#>
$CREATE = "CREATE TABLE $TABLE (AD_Machine varchar(150) not null PRIMARY KEY, `
	OU varchar(100),DistinguishedName varchar(max),PasswordLastSet datetime, `
	OS varchar(100),ServicePack varchar(100))"
#/////////////////////////////////////////////////////////
<#Setting up object variables
	to be used for AD lookup#>
	$TIME = [datetime]::today.adddays(-$DAYS)
$LOOKUP = (Get-ADOrganizationalUnit -LDAPFilter "(Name=$ORGUNIT)")
	$ADARRAY = (Get-ADComputer -SearchBase $lookup.DistinguishedName -properties `
			name,passwordlastset,operatingsystem,operatingsystemservicepack `
			-Filter 'passwordlastset -ge $TIME')  
<#Setting up object variables
	to be used for AD lookup#>
	$TIME = [datetime]::today.adddays(-$DAYS)
$LOOKUP = (Get-ADOrganizationalUnit -LDAPFilter "(Name=$ORGUNIT)")
	$ADARRAY = (Get-ADComputer -SearchBase $lookup.DistinguishedName -properties `
			name,passwordlastset,operatingsystem,operatingsystemservicepack `
			-Filter 'passwordlastset -ge $TIME')  
<#Connect and cleanup the AD table
	Connection remains open for writting#>
$SQLCON = New-Object System.Data.SqlClient.SqlConnection("Data Source=$SQLSRVR; `
			Initial Catalog=$DB;Integrated Security=SSPI")
	$SQLCON.open()
		$SQL = $SQLCON.CreateCommand() 
			$SQL.CommandText ="DROP TABLE $TABLE"
				$SQL.ExecuteNonQuery() > $null
		$SQL.CommandText = $CREATE
			$SQL.ExecuteNonQuery() > $null
<#Begin loop through the ADARRAY for
	Variables and begin inserting Rows to table#>
	$X = 0
ForEach($OBJECT in $ADARRAY){
	
	$NAME = $OBJECT.Name
		$OU = $OBJECT.DistinguishedName.ToString().Substring($OBJECT.Name.ToString().Length+4)
			$DN = $OBJECT.DistinguishedName
				$PWDLS = $OBJECT.PasswordLastSet
					$OS = $OBJECT.OperatingSystem
						$SP = $OBJECT.OperatingSystemServicePack
						
#\\\\Any Table Data to be written goes here:\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
	$INSERT = "INSERT $TABLE VALUES ('$NAME','$OU','$DN','$PWDLS','$OS','$SP')"
	$SQL.CommandText = $INSERT
#////////////////////////////////////////////////////////////////////////////////////////	
		$SQL.ExecuteNonQuery() > $null
$X = $X + 1			
}
"$X Records written to $TABLE in database $DB on server $SQLSRVR"
<#Cleanup variables and close connections#>
$SQLCON.Close()

 

Overview: 

We have 5 key variables to work from here:

  1. $DB – Name of Database to write to
  2. $SQLSRVR – Name/IP of the SQL server
  3. $TABLE – Table to build this data to
  4. $DAYS – Age of machines to pull from AD
  5. $ORGUNIT – The base OU to search through recursively

 

These of course are set to preference or need.

Now what the script does is, it figures out the date using the datetime function in .net factored by the number of days back you declare.

Then it looks up and stores the base OU we will search through then builds the object with the AD Objects it finds.

Next it instantiates the SqlClient object and makes a connection to the server and database we specified in our variables.  We drop the table specified, then recreate the table.

Now the real work begins, we loop through the AD Objects one by one and cherry pick the specific properties out that we want from the object (an area that PowerShell excels at I might add) and declare them as variables to be finally written to our database table.

And for good measure we count each loop and store that so we can see how many records were found and attempted, then cleanup all our variables used during the script.