TenBrink Tech Technology | Life

21Jan/08

Latest IBM v. Microsoft Collaboration Numbers

A post over at CNET this morning gives us an insight into the latest numbers in the messaging and collaboration space between Microsoft and IBM.

Microsoft says that in the last six months of 2007, more than 300 big companies, representing 2.8 million people, began switching from IBM software onto Exchange Server, Office and SharePoint Server.

...

Gartner analyst Matt Cain says that among enterprises with more than 100 users, Microsoft holds about 62 percent share, compared with about 26 percent for IBM.

"Microsoft has been picking up a percentage point or two of e-mail market share based on seats for the past few years, and we expect that to continue," Cain said in an e-mail interview.

All this while Microsoft has announced a new set of migration tools and services to assist customers moving from the IBM to the Microsoft platform.

  • Share/Bookmark
9Jan/08

Today’s Fun with PowerShell

On this episode of Fun with PowerShell, we dive into the realm of retrieving account information from various sources using the DirectoryEntry object. If you are familiar with the ADSI interfaces, this should give you a good idea of how to transfer knowledge from that medium to the PowerShell/.NET way of thinking.

All the code examples are based on work I've done today, but as always YMMV. There's always a better, faster, more creative way to do coding, and I highly encourage that thinking.

So, what is a DirectoryEntry object? Simply an instance of that class, borrowed from the .NET framework. You can use a DirectoryEntry to access any of the ADSI service providers, so LDAP, IIS, NDS, and WinNT. I am going to touch on LDAP and WinNT for this article.

Let's start with the basics. You have an Active Directory domain. You want to find all servers in that domain (those that have checked in, at least). First, you need a starting point for your search.

PS C:\> $ad = New-Object DirectoryServices.DirectoryEntry("LDAP://dc=company,dc=com")

Could I specify a particular domain controller? Sure!

PS C:\> $ad = New-Object DirectoryServices.DirectoryEntry("LDAP://domainctrl1.company.com:389")

What if we wanted to start further down the tree?

PS C:\> $ad = New-Object DirectoryServices.DirectoryEntry("LDAP://ou=something,ou=somewhere,dc=company,dc=com")

or

PS C:\> $ad = New-Object DirectoryServices.DirectoryEntry("LDAP://domainctrl1.company.com:389/ou=something,ou=somewhere,dc=company,dc=com")

Can we make it even shorter? If your workstation is a member of the domain you are looking for, then we can.

PS C:\> $ad = [ADSI]

This is very nifty. At the lowest level, we are just selecting a particular object in the directory. For the purposes of our search, this happens to be a root or OU level of the directory. You could pluck out a particular individual object and manipulate from there. Try it with your user account.

PS C:\> $user = New-Object DirectoryServices.DirectoryEntry("LDAP://cn=Dillon TenBrink,ou=geeks,dc=company,dc=com") | fl *

Now that we have our $ad variable, representing our search root, we need a searcher.

PS C:\> $searcher = New-Object DirectoryServices.DirectorySearcher($ad)

Once we have a searcher, we have a selection of settings to flip on it to execute our query.

PS C:\> $searcher

CacheResults             : True
ClientTimeout            : -00:00:01
PropertyNamesOnly        : False
Filter                   : (objectClass=*)
PageSize                 : 0
PropertiesToLoad         : {}
ReferralChasing          : External
SearchScope              : Subtree
ServerPageTimeLimit      : -00:00:01
ServerTimeLimit          : -00:00:01
SizeLimit                : 0
SearchRoot               : System.DirectoryServices.DirectoryEntry
Sort                     : System.DirectoryServices.SortOption
Asynchronous             : False
Tombstone                : False
AttributeScopeQuery      :
DerefAlias               : Never
SecurityMasks            : None
ExtendedDN               : None
DirectorySynchronization :
VirtualListView          :
Site                     :
Container                :

From here, we go to work defining our filter and the properties we would like to get back.

PS C:\> $searcher.Filter = "(&(objectClass=Computer)(operatingSystem=*Server*))"

PS C:\> $searcher.SizeLimit = 1000

PS C:\> $searcher.PropertiesToLoad.Add("cn")

PS C:\> $searcher.PropertiesToLoad.Add("operatingSystem")

You could define more options if you needed. Check the documentation on the DirectorySearcher class for more information.

From here you can execute the .FindOne() or .FindAll() methods to return the results of your query.

Let's move on to a different animal using the DirectoryEntry class to show some versatility. This time we'll use the WinNT ADSI interface.

The WinNT interface is still, in my opinion, the best way to get information on local accounts and groups remotely on a Windows box. Here we are going to use it to get a list of the local users on a server PDX01. First, like before, we create our DirectoryEntry.

PS C:\> $Sys = New-Object DirectoryServices.DirectoryEntry("WinNT://PDX01,computer")

If you performed a $Sys | fl * at this point, you can see all the properties of this object, just like your user account from AD above when we're using the LDAP provider. What we're after though, is the members, or "children", of this computer.

PS C:\> $Sys.children

Executing this command will return users, groups, and services. Since we're just after the users, let's filter it down.

PS C:\> $Sys.children | where {$_.SchemaClassName -match "User"}

Much better. Now we have our list of users. If we wanted to save this for later, dump it into a variable.

PS C:\> $Users = $Sys.children | where {$_.SchemaClassName -match "User"}

And then pipe all the details out to the console.

PS C:\> $Users | fl *

There you go.

From both of these starting blocks, you can then use your scripting prowess to harness the results of these queries to do your bidding. Take the AD server query, drop it into a loop with the local account query, and you have a quick and powerful local account audit script. Extend it a little more and take the local users, filter by their password age attribute and you have a functional password age checking script for local accounts. The possibilities are endless once you can retrieve the data sets.

Is this easier in vbScript or VB.NET?

My personal preference is to write these particular queries in VB.NET because I typically have more data analysis to do against other systems. Just my preference. That's not to say I couldn't write those interfaces and analysis in PowerShell; just that I haven't found a need quite yet. The PowerShell way is very useful though, and quicker, when just plain, raw data is required and I use it frequently in those scenarios.

Benefits over vbScript? You can walk though this line by line, in real time, and adjust as you go to get your results exactly the way you want them. You wouldn't want to write that script, execute, correct, and run again from the start over and over until you got what you wanted, right? PowerShell provides the advantage of having feedback line-by-line as you progress. Then, save your refined statements as a .ps1 file and reuse it later or call it in other scripts.

Happy scripting!

  • Share/Bookmark
7Jan/08

Microsoft Search Filter Pack

Missed this one in the holiday shuffle and updates to the blog. Microsoft has created a package containing all of the iFilters you would need to read the following filetypes:

  • .docx (Microsoft Office 2007 Word Document)
  • .docm (Microsoft Office Word Macro-Enabled Document)
  • .pptx (Microsoft Office 2007 PowerPoint Presentation)
  • .xlsx (Microsoft Office 2007 Excel Worksheet)
  • .xlsm (Microsoft Office Excel Macro-Enabled Worksheet)
  • .xlsb (Microsoft Office Excel Binary Worksheet)
  • .zip (WinZip File)
  • .one (Microsoft Office OneNote Section)
  • .vdx (Microsoft Office Visio Drawing)
  • .vsd (Microsoft Office Visio Drawing)
  • .vss (Microsoft Office Visio Stencil)
  • .vst (Microsoft Office Visio Template)
  • .vsx (Microsoft Office Visio Stencil)
  • .vtx (Microsoft Office Visio Template)

for the following programs:

  • Office SharePoint Server 2007
  • Search Server 2008
  • SharePoint Portal Server 2003
  • Windows SharePoint Services 3.0
  • Exchange Server 2007
  • SQL Server 2005
  • SQL Server 2008

Head over to the download page for installation details.

  • Share/Bookmark
6Jan/08

Moving the Blog

Welcome to all of my loyal (and occasional too) readers to the new home of the blog. After 4+ years of running the blog on various versions of blogging servers on my own hardware, I am simplifying my life by letting someone else do the heavy lifting. In this case, Blogger.

For those of you who have migrated over to the feed link, this shouldn't even hurt a bit, as your reader will just swap over to the new feed. If you have any hard links to old articles, unfortunately those will no longer work.

Thanks for tagging along in the change. I've got a bunch of things planed for 2008, so stay tuned.

  • Share/Bookmark