Saturday, September 29, 2012

Powershell, WMI, rapidfailprotection, and Set-WmiInstance

Recently, I've been having to admin IIS7+ with WMI. I was pretty comfortable reading WMI data with Powershell, but the need to write data just hadn't come up. I figured as easy as it was in C#, it would be even easier with Powershell.

For the most part, it is. There's lots of examples on how to do it.

There's other settings which aren't so straightforward, though. Application pool rapidFailProtection was the one that led me on my investigation. It's contained in an EmbeddedObject, which isn't really a WMI object. For example, it has no __PATH.

Setting it directly didn't work, and neither did Put().

The trick is to put the EmbeddedObject into a temporary variable, SetPropertyValue on the temp variable, and pass the temp variable back as an argument to Set-WmiInstance.
$creds = Get-Credential
$ComputerName = "target.example.com"  
$appPool = (Get-WmiObject -Namespace "root\WebAdministration" `
            -Class "ApplicationPool" `
            -ComputerName $ComputerName `
            -Credential $creds `
            -Authentication PacketPrivacy | `
            where { $_.Name -eq "DefaultAppPool" })
            
if( $null -ne $appPool )
{
    write-host $appPool.Name
    $failureNode = $appPool.Failure
    $failureNode.SetPropertyValue( "RapidFailProtection", $false )

    Set-WmiInstance `
        -InputObject $appPool `
        -Arguments @{ failure = $failureNode }
}

(Get-WmiObject -Namespace "root\WebAdministration" `
            -Class "ApplicationPool" `
            -ComputerName $ComputerName `
            -Credential $creds `
            -Authentication PacketPrivacy | `
            where { $_.Name -eq "DefaultAppPool" }).Failure

If you examine the WMI class you created at the beginning of the script, you won't see the change. Refreshing from the source (or just looking on the server) shows the updated value.

Tuesday, June 21, 2011

LulzSec and the State of Security

Well, the skiddies sure have been busy, haven't they? Starting with Sony's Playstation Network, to (supposedly) the entire UK 2011 Census, LulzSec has appeared over and over again in the news.

It was announced that a 19-year old mastermind has been arrested in the UK. Well, that should do it, right?

Here's some thoughts about that.

  • It is pretty hard to claim that LulzSec even has a leader. They act more like a collective. Anyone can claim to be "LulzSec".
  • Most of the attacks have been easy. No "mastermind" is needed.
  • It is more likely that the active participants are among the least-sophisticated of hackers. They are just the noisiest.
Those aren't really important, though. What's important is that these vulnerabilities have always been there. LulzSec is only the first to admit that they got to this data. It is all too likely that groups or individuals who were more interested in the data than the publicity got there first.

It isn't as if there hasn't been ample discussion and warnings about security. I've been on the wrong side of expediency too often to believe that. The story is always the same: a variation of "we don't need to worry about that, we need to worry about shipping".

It is a shame that it all came to this, that it takes a bunch of kids using common tools to get past the denials and false assurances of these institutions in order to get the kind of attention that these issues deserve. There will be many innocent victims because institutions who have the resources and knowledge to be among the best failed their most basic function: keeping your money safe.

Saturday, July 10, 2010

Operations is as Important as Development

A couple of recent events have inspired me to write this post. The second was Reddit's needing help. The first was an event on my current contract.

My takeaway from Reddit's problem is brief: they finally figured out that just adding new features isn't enough. They have to get their house in order, and they have to take steps to keep it that way. To be fair, I don't know that the source of their problem was poor operational planning, in fact, it sounds like they devote a fair amount of time and effort to it.

The event at work was something of which I've seen way too much. A business wants to roll out a pretty sophisticated reporting application, high availability, super fast - you know, what everyone wants. My part of the whole thing was to determine what hardware and software resources to provide, and then build them out (it's a big enterprise shop, so there's a lot more "fun" associated with it).

It is easy to say "I want multiple web servers", it is another thing to build for multiple web servers. There's a few ways to do it, and what direction is chosen determines what to build.

This particular business not only hadn't really thought about it, they didn't want to think about it. Okay, fine, I can build for that, too - but it is gonna cost them. To the tune of about a half million dollars, just to start. With only a little bit of planning and forethought, by utilizing resources already in place they could get everything they wanted for a few thousand. That's a business decision - if the business can justify that much money, it's their budget, and who am I to complain?

While I may not complain, I can't help but notice that this doesn't really seem like smart business. In that particular case, I really don't know enough about what is going on from the business side to really make that kind of judgement.

However, I have been in enough situations where I did know enough about what is going on to be able to make that judgement. I've seen it enough that I don't want to be in a position where those decisions are made, or diminished. In fact, it is in my best interest to let these shops ignore this importance - because I charge top dollar for coming in and fixing it after the fact. If a shop wants to make a poor business decision which is good for my business...well, that's a good business decision on my part, isn't it?

If you're not bothered by the idea of getting yourself in such a tight bind that you have to shell out thousands of dollars for someone like me (and yes, thousands of dollars is accurate. Sometimes tens of thousands), then save yourself some time and stop reading.

System administration shouldn't be considered after the fact. It shouldn't be considered a necessary evil. It deserves as much prominence and dedication as any other part of the development process. An application isn't just the application that is installed or written - what it is running on is just as important.

System administration has it's own demands,it's own skillsets, it's own schedule, and it's own rhythm. This should be recognized up-front, and it should be given first-class priority. I'm probably being repetitious at this point, but it seems like it really isn't appreciated.

So, I'll say it again: too many businesses, large and small, waste money and time because they don't recognize the importance of their operations, and treat them as afterthoughts. Too many businesses limit themselves, their options, their very potential, because they don't recognize this.

I started to write this with an eye towards specific steps, specific considerations, and a lot of ideas to think about for implementing this. As I wrote, though, it only became clearer that the first step was pointing out what doesn't seem obvious: operations are important. Learn that, know that, believe that, and live that, and you won't have to worry about paying someone like me a ridiculous amount of money when it is least convenient to you.

Ignore this, and that's fine with me. My contact info is to the right, and I sincerely hope to hear from you.

Monday, June 21, 2010

Exporting MongoDb with Powershell

I'm just going to leave this right here. This fixes up the output from mongoexport to create an array, suitable for XMLSpy...

function Export-Wmi
{
 Param (
  [Parameter(mandatory=$true)]
  [string]
  $DbName,
  
  [Parameter(mandatory=$true)]
  [array]
  $CollectionNames
 )
 
 Process {
  $CollectionNames |
  foreach {
   $output = ""
   $cmd = ""
   $docs = C:\Path\To\Mongo\bin\mongoexport.exe `
    --db $DbName `
    --collection $_ `
    2>$null
   
   $output += "["
   $bfirst = $true
   foreach( $doc in $docs )
   { 
    if( -not $bfirst )
    {
     $output += ","
    }
    
    $output += $doc
    
    $bfirst = $false
   }
   
   $output += "]"
   
   $output | Out-File -FilePath "C:\Path\To\Data\$_.json"  
  }
 }
}

Export-Wmi -DbName "reports" -CollectionNames @("coll1", "coll2" )

Wednesday, June 2, 2010

Powershell, MongoDB, and WMI

I had reason to write a short cmdlet which converts WMI objects to MongoDB docs. It ain't much, but it works so far:

 [Cmdlet( VerbsData.ConvertTo, "MongoDoc" )]
 public class ConvertToMongoDoc : Cmdlet
 {
  [Parameter( Mandatory = true, ValueFromPipeline = true )]
  public PSObject InputObject { set; get; }

  protected override void ProcessRecord()
  {
   Document converted = (Document)WmiConvert( InputObject.BaseObject );
   this.WriteObject( converted );
  }

  protected object WmiConvert( object obj )
  {
   if( null == obj )
    return null;

   object newObj = obj;


   Type objType = obj.GetType();

   TypeCode objTypeCode = Type.GetTypeCode( objType );
   String objTypeName = objType.FullName;
   
   if( objType.IsGenericType )
    return obj;

   switch ( objTypeCode )
   {
    case TypeCode.String:
     return obj;
   }

   switch ( objTypeName  )
   {
    case "System.TimeSpan":
     return ( (TimeSpan)obj ).Ticks;

    case "System.Int16":
    case "System.UInt16":
     return System.Convert.ToInt32( obj );

    case "System.UInt64":
    case "System.UInt32":
     return System.Convert.ToInt64( obj );

    case "System.Byte":
     return null;

    case "MongoDB.Driver.Document":
     return obj;
   }

   if( objType.IsArray )
   {
    ArrayList aTmp = new ArrayList();
    foreach ( var s in (object[])obj )
    {
     aTmp.Add( WmiConvert( s ) );
    }
    return aTmp;
   }

   if( 0 == objTypeName.IndexOf( "System.Management." ) )
   {
    Document tmpdoc = null;

    switch( objTypeName )
    {
     case "System.Management.ManagementObject":
     case "System.Management.ManagementBaseObject":
      tmpdoc = new Document();
      ManagementBaseObject mbo = (ManagementBaseObject) obj;
      tmpdoc.Add( "WmiPath", mbo.SystemProperties["__PATH"].Value );
      tmpdoc.Add( "WmiServer", mbo.SystemProperties["__SERVER"].Value );
      AddPropsToDoc( tmpdoc, mbo.Properties );

      newObj = tmpdoc;
      break;

     default:
      break;
    }

    return newObj;
   }
   return newObj;
  }

  protected void AddPropsToDoc( Document doc, object obj )
  {
   foreach ( var propData in (PropertyDataCollection)obj )
      {
       doc.Add( propData.Name, WmiConvert( propData.Value )  );
      }
  }
 }

Hope this helps.

Friday, May 14, 2010

Enumerating Powershell NoteProperties

I recently was asked to stuff a custom PSObject into a bunch of key value pairs, so I thought I'd put it here. Is there a better way?

$props = ($File | get-member -MemberType NoteProperty)
foreach( $p in $props )
{
     # write-verbose (invoke-expression "`$File.$($p.Name)")
     $doc.Add( $p.Name, (invoke-expression "`$File.$($p.Name)") )
}

I Want an Online-persona Manager

There's been a lot of hubbub about Facebook and its changing privacy settings. The short version is that they are changing them to the advantage of people who want to make a buck out of you and your friends. It didn't start out that way, and the change has people in a bit of an uproar.

Thing is, Facebook does serve a valuable function - otherwise there would be nothing to exploit. An easy way to keep a business account, and a personal account. Many people use LinkedIn (for professional contacts) and Facebook (for personal) in this manner, including myself.

What the Facebook uproar is making clear is that people value the partitions they build into their lives, and want those partitions maintained online. Another thing that is clear is that as users, we can be sure that policies will change, and we won't like some of those changes.

I don't want to quit Facebook. I like Facebook, for what it is. I don't begrudge Zuckerberg a few bucks off of me, as long as he provides a service I want to use.

What I want is an easier way to manage my profiles, so that I not only have control over what's published, and where, and I want it to be easy.

I want to maintain my own profiles in a centralized location - my hard drive, my backup.

I want to write something once, and then choose, with high granularity, where it will be published.

I want it to be universal, and work with damn near everything.

I want it to be simple, with one interface, like Pidgin does for IM.

I want it to be scriptable, because by now I'm just being greedy :)

I don't want project Diaspora. I'm happy for the kids, and I wish them well, but all they promise is that I'll either have to fire up a server for myself, or I'll have to trust someone else. Again.

I trust my laptop. I trust my mobile phone (sort of). I trust my thumb drive. I trust TrueCrypt. It is my data, and I should control it.

There's a reason businesses try to find out so much about us: it has value. Google has the luxury to walk away from the extra revenue; they're getting enough.

Interestingly enough, Microsoft has an initiative that addresses some of the problem. Called U-Prove, it is BSD-licensed to help drive adoption. It primarily deals with managing both identity and authorization in financial transactions - I don't know if it could be adapted to social sites. This Ars article goes into greater depth.

I dinked around with building something like this on my own, but honestly, it looks like a bit more work than I can tackle right now. So, if there's somebody out there that thinks is a good idea, and has the wherewithal to pull it off, please steal this idea - I'll be one of your early adopters, I promise.

Update: I came up with another way to describe it while discussing this privately (Hi, Tracey!):

I've got six accounts in Outlook right now, all pointing to different places. My personal domains don't know about my google addresses, and heck, my google addresses don't even "know" about one another. (Reading the Spam folders for each one is an education in targeted advertising.) I want the same thing, only for the various social networks.

Tuesday, May 11, 2010

Powershell grep'ing

I've been asked about searching and replacing in files a few times, so I thought I'd put an example up here. This is a way to do it - and you'll almost certainly want to change it around to better suit your scenario.

cd C:\Users\michael.DOMAIN\Workspace\Powershell
function pgrep
{
 Param (
 
  [string]
  [parameter(mandatory=$true)]
  $Like,
 
  [bool]
  $Recurse = $false,
  
  [string]
  $BasePath
 )
 
 Process {
  if( -not $BasePath )
  {
   $BasePath = $PWD
  }
  
  # there's gotta be a slicker way
  $recurse_string = ""
  if( $Recurse )
  {
   $recurse_string = "-Recurse"
  }
  
  Invoke-Expression "Get-ChildItem -Path $BasePath $recurse_string" | 
  where {$_.PSIsContainer -eq $false } |
  foreach {
 
   $file = $_
   # $file.FullName
   # Get-Content -Path $file.FullName | where { $_ -eq "MachineName" }
   if( Get-Content -Path $file.FullName | where { $_ -like $Like } )
   {
    $file
   }
  } 
 }
}

function preplace
{
 Param (
  [string]
  $Path,
  
  [string]
  $From,
  
  [string]
  $To
 )
 
 Process {
  $fi = New-Object -TypeName System.IO.FileInfo -ArgumentList $Path
  $tmpfile = "$($fi.DirectoryName)\$($fi.Name).tmp"
  Remove-Item -Path $tmpfile -ErrorAction SilentlyContinue
 
  Get-Content $Path | 
   foreach {
    $line = $_
    $line.Replace( $From, $To )
   } |
   Add-Content -Path $tmpfile
  
  Remove-Item -Path $Path -ErrorAction SilentlyContinue
  Rename-Item -Path $tmpfile $Path
 }
}


pgrep -Like "*MachineName*" -BasePath C:\Users\michael.DOMAIN\Workspace\Powershell |

foreach {
 $fi = $_
 Write-Host "updating $($fi.FullName)"
 preplace -Path $fi.FullName -From "MachineName" -To "MachineFoo"
}

Sunday, May 2, 2010

Getting Command Line Parameters Using Powershell

I'm just going to leave this here...
(gwmi win32_process -filter "name='powershell.exe'").commandLine

Friday, April 9, 2010

Open Source Installation Packages for Windows

Well, at least MS is acknowledging the problem: installing (not to mention developing) OSS applications on Windows is a complete pain in the ass. They have announced some vaporware to deal with the situation.

Now, if they would only take the same approach with everybody's app. Windows would really benefit from a Debian/RedHat package management system: A single place to look for applications and installers. It works for Apple's iPhone, doesn't it?

Friday, April 2, 2010

Emacs, Clojure, and Windows 7

Okay, I had to wrestle with this. Maybe that makes me dumb, but if you're reading this, then you ain't doin' much better. I've had an on-and-off again, love/hate relationship with emacs over the years, and I'm swinging back to "on/love" while dinking around with Clojure. Emacs really is the best Lisp-type environment, even on Windows.

To give credit where due, I started with this good post on freegeek.in, but some bits were outdated.

Pre-requisites

First, get emacs installed. Find the latest version in this folder, and extract it someplace - no installation is really necessary.

You also need git. Let's assume you get through all of that.

Last, but not least, you should have a JDK installed.

Add the path to git and java.exe to your PATH, and set JAVA_HOME to your JDK. If you don't want to do that, then start a command prompt, set them manually, and do anything emacs-y from there.
set PATH=%PATH%;c:\sys\git\bin;c:\sys\emacs-23.1\bin
set JAVA_HOME=c:\program files\Java\jdk1.6.0_19
runemacs

Emacs Starter Kit

Next, install the Emacs Starter Kit. This is a huge time-saver. Many of my previous complaints about emacs tended to be having to learn so much just to modify the environment. This takes care of a majority of that. One of the nice, and really important bits is ELPA - a package management system for emacs. In one fell swoop, 80% of my complaints have been silenced.

Anyway, download the ESK from github

git clone git://github.com/eschulte/emacs-starter-kit.git C:\Users\<userdirectory>\AppData\Roaming\.emacs.d

If you have a C:\Users\<userdirectory>\AppData\Roaming\.emacs file, rename it. You can copy it to custom.el, and it will be used as normal. Most of the action occurs in init.el, so that's a good place to look if you really don't like something.

Nope, we're not quite there yet. Before you can use it, you need to install org-mode.

cd C:\Users\<userdirectory>\AppData\Roaming\.emacs.d
git submodule init
git submodule update


Fire up emacs, and M-x package-list-packages. Scroll right on by that tempting "clojure-mode", and put your cursor on "swank-clojure", then press "i" (to select it for installation), then "x" (to start the installation).


Okay, here's where I ran into a problem: when trying to use ELPA, I got the following error: "Local variables entry is missing the suffix". The nice thing about obscure error messages is that they are usually pretty easy to search on. (There's a patch here, only the file name is "package.el"

You'll be adding a function, and modifying package-unpack-singe to use it.

(defun package-write-file-no-coding (file-name excl) 
 (setq buffer-file-coding-system 'no-conversion) 
 (write-region (point-min) (point-max) file-name nil nil nil excl))

The ESK instructions say to build org-mode after that, but launching emacs seemed to take care of that.

Using it

Woooo! Installed! Isn't this easier than NetBeans? (well, actually "yes" for me, since it was some frustration with Enclojure that drove me back to emacs)

Launch emacs, and type M-x slime. If you have everything set up right, you should be prompted to install clojure. This will not only install clojure, but also get you the swank-clojure.jar you'll be needing for projects.

Projects

Assuming you got your SLIME prompt in the step before, creating a project is easy, but not as easy as it could be.

Create the following directory structure wherever it is you want your project to go:

root
  +--src
  +--lib
  +--classes
In the lib directory, put your clojure, clojure-contrib, and swank-clojure jars. You can find them in C:\Users\<username>\AppData\Roaming\.swank-clojure Then you should be able to start a new project with:

M-x swank-clojure-project

That should do it - hope it helps

Tuesday, January 5, 2010

Cleaning up OpenNMS Assets

I've had OpenNMS running on the network for awhile, and here's a problem I ran into: my network is too dynamic. Specifically, it doesn't play nice with DHCP clients. Every time the IP address changes, OpenNMS considers it a new node.

What's screwed up is if you delete the old nodes, the asset info sticks around, even if you didn't add any actual asset information.

I got things straightened up enough that OpenNMS and I are getting along fairly well. There was still all this old asset information gumming up the works. I didn't see anything in the UI or help to get rid of them, so I did it the hard way.

Log into the postgres box hosting the database, and don't forget to use it. Then run the following:

delete from assets 
using node
where node.nodeid = assets.nodeid
and node.nodetype = 'D'

That should clear it up, and it doesn't appear to break anything. If you have any trouble after running this, please let me know in the comments, and I'll look into it (since it will probably be a problem for me, too).

Hope this helps.

Monday, January 4, 2010

Untangle, the DIY Network Gateway Software

I like building my own home routers. The ones you can pick up from NewEgg are nice, and they do their job admirably. Sometime back, though, I developed a taste for building my own.

Until just recently (we'll get to that), I was running pf on FreeBSD. Love it. Best damn firewall software out there, and if you need something really custom, but don't want to spend a lot of money, that's the way to go.

My old firewall was a little Epia mini-itx (that's small and low-powered), but it handled three network segments just fine, as well as a couple of ancillary tasks. It's been dying for awhile, though. Since it's my house, and that's the only place I get to really play fast-and-loose, I kept it going.

Well, it died, as these things do, last weekend.

I found an old box - another Epia, as it happens - with only two network ports (no wireless segment, for now), and set up Untangle, the "Open Source Network Gateway". There wasn't much to it, put in the CD, answer some questions, do a lot of waiting (the temporary machine is really slow).

It can be set up as a router or a bridge, the latter permitting easy integration into an existing network. There's no need to set up anything on the clients; everything happens transparently. Some of the niftier free modules include an ad blocker, virus blocker (http, smtp, pop3, imap - again, with no configuration), web filters, and so on.

It also provides the typical soho services: DHCP, DNS, port forwarding, etc.

All of that is open source, and free to download. They also have additional modules, on a subscription basis.

So far, it works well for the two segments it is handling. Performance is fine, as long as I don't get crazy with the various modules. There's also a bunch of administration functions I haven't delved into, so I may not be giving it the credit it deserves.

The new hardware should be in this week - it's looking like four network ports, maybe a wifi card, and a nice little Atom processor. It should be faster, in general, but it is going to have a lot more to do. I'll update when I've got a stronger opinion about it.

Wednesday, December 9, 2009

Capturing Output as String and Variable in Powershell

I'm embedding a posh shell into a C# app I'm writing, and I needed a way to capture the text output of the app, as well as the results as an array. This is what I came up with:

Runspace runspace = RunspaceFactory.CreateRunspace();
runspace.Open();

runspace.SessionStateProxy.SetVariable( "location", "c:\\" );
Pipeline pipeline = runspace.CreatePipeline();
pipeline.Commands.AddScript( "get-childitem $location" );

// this splits the output into the text and variable
Command cmd = new Command( "tee-object" );
// this is where the result array will end up
cmd.Parameters.Add( "variable", "invoke_results" );
pipeline.Commands.Add( cmd );
// forces the rest of the output to string
pipeline.Commands.Add( "out-string" );

Collection<PSObject> results = pipeline.Invoke();

var errors = pipeline.Error;

if( 0 < errors.Count )
{
 // there might be more. For now, we read the first
 var oneError = errors.Read( 1 );
 ConsoleColor formerConsoleColor = Console.ForegroundColor;
 Console.ForegroundColor = ConsoleColor.Red;
 Console.WriteLine( "Error: {0}", oneError[0] );
 Console.ForegroundColor = formerConsoleColor;
}
else
// hooray, no errors
{
 object[] resArray = (object[])runspace.SessionStateProxy.GetVariable( "invoke_results" );

 Func<List<String>, object, List<String>> nameAcc =
  ( n, o ) =>
  {
   n.Add( o.ToString() );
   return n;
  };

 List<String> names = resArray.AsEnumerable().Aggregate( new List<String>(),
        nameAcc
  );

 foreach( var list in names )
 {
  Console.WriteLine( list );
 }
}

runspace.Close();
This was much easier than trying to implement my own custom host.

Tuesday, December 8, 2009

Facebook Scalability Story

Here's a synopsis of a presentation given as part of the CNS lecture series, discussing Facebook's architecture.

Even though it is just an overview, it is pretty detailed, and gives interesting little factoids such as:
  • 600k photos/sec
  • php for the front end
  • 30K servers, in two datacenters
  • ”Work fast and don’t be afraid to break things.”
There's lots of neat stuff in there.

Thursday, December 3, 2009

MS SQL Server Pivot Tables

Another one for the "don't lose me" pile...

MS SQL 2005 and onward have a PIVOT function, which acts like an Excel pivot table.

Notes here.

Wednesday, November 25, 2009

Statistical Data Mining Tutorials

Just a little note to myself to not lose this link.

Tuesday, November 24, 2009

Listing User Last Logon with Powershell

This script assumes that you have enabled auditing on successful logins (by default, it doesn't).

The general process it follows is:
  • retrieve the Security event log
  • pulls login information up to the last reboot
  • gets unique usernames and the time they logged in
  • writes it all out to a text file
It's still a little raw, but it works. It runs very slow over the network; I'll work up one that uses the PSJob facilities...


function getLastBoot( $computername )
{
$wmi = Get-WmiObject -Class Win32_OperatingSystem
return $wmi.ConvertToDateTime( $wmi.LastBootUpTime )
}

function getTopDates()
{
$logins = @()
$input | foreach {
$rec = $_

# this is ugly...I'm going thru the list twice
$hasit = ($logins | where {($_.UserName -eq $rec.UserName) -and ($_.MachineName -eq $rec.MachineName)})

if( $hasit )
{
for( $x = 0; $x -lt $logins.Count; $x++ )
{
if(($rec.UserName -eq $logins[ $x ].UserName ) -and
($rec.MachineName -eq $logins[ $x ].MachineName ))
{
$logins[ $x ] = $rec
}
}
}
else
{
$logins = $logins + @(,$rec)
}
}
return $logins
}

$start_time = (Get-Date)
Write-Host "starting all $start_time"

$target_computers = @( "dal1mspwb16",
"dal1mspwb19",
"dal1mspwb36",
"dal1mspwb37",
"dal1mspwb12",
"dal1mspwb35")

# $target_computers = @( "dal1msdwb34" )

$target_computers | foreach {
$target = $_
$lastboot = getLastBoot( $target )

Remove-Item "iis_logins_$target.txt" -ErrorAction SilentlyContinue


Write-Host "processing $target :" (get-date)
Get-EventLog -LogName "Security" -ComputerName $target -After $lastboot |
select -Property UserName, MachineName, TimeGenerated -Unique |
sort -Property TimeGenerated |
getTopDates |
Out-File -Append -FilePath "iis_logins_$target.txt"

Write-Host "completed $target :" (get-date)
}

$end_time = (Get-Date)

Write-Host "complete"
Write-Host "Started: $start_time"
Write-Host "Finished: $end_time"
Write-Host ($end_time - $start_time)

Thursday, November 19, 2009

Creating System Restore Points with Powershell

Getting ready to install a new video driver? What about that "interesting" piece of software you found?

Aren't you worried that it is going to screw up your computer?

Well, if so, Windows XP/Vista/7 have a facility known as "System Restore Points". Basically, these are snapshots of your filesystem. There is a good chance they are already enabled, and being used by Windows Update.

What about those other times, though?

If you have Powershell 2.0 installed (whaddya mean, you don't? Get on it!), then you have a couple of commands to help you out:

Checkpoint-computer creates a system restore point.

Restore-computer reverts to the specified restore point

So, before you install that problematic driver/update/app, this is a quick and dirty way to cover your butt.

Be warned, though, this will restore everything - including any changes to any files you may have made.

Wednesday, November 18, 2009

Tracing Internet Explorer

eJohn has this article discussing dynaTrace Ajax, a utility for IE6-8 performance tracing. Sounds like neat stuff:
Not only can you see the execution count for your defined JavaScript methods but you can also see execution time for the built-in DOM methods! Wondering what native method calls are slowing down your application? Wonder no more. From the HotSpot view you can filter by DOM or regular JavaScript and see exactly where execution time is going and what methods are so slow.

Worth a look.