Skip navigation

Monthly Archives: May 2011

So as I sit here, still stuck on an energy rush from this weekends excitement and the one to come, it hit me. 

How easily do things grab hold of us and jerk us into new directions.  I’m generally a very focused worker.  I’ve lately been a bit stand offish about my video game play, and been anti gadget.

Yet, here I am, tinkering endlessly with this modified nook, anticipating long hours of play with my friends this weekend, and unable to focus on my job.  Albeit I’m doing my job, its with great determination that I remain on task.

How much more or less is our faith a part of our being when we are so easily pulled this way and that? That our hearts and minds are so easily redirected.  I’m thankful to say that I’ve continued to read the word, remain in prayer, and give glory to God in what I’m doing and in what is being done for me… this time.  This isn’t always the case for me, or for others.  To witness that these idols come and go, serves as an amazing contrast to Gods steadfast nature.  Why would we need anything more? Why do we forget that?  That answer is both simplistic and complex, sin, or that our chief idol is ourselves and not our Creator. 

I realize that sounds sort of, dark.  Generally thinking of the “aftermath”conjures thoughts of destruction and loss.  However, the only thing lost is another year of my life, but the gains were enjoyable!

Lets start with the presents (so far).  I’m going to start with the immediately tangible present my wife got me….  A nook color.

May 26 (210)

 

Here’s the thing.  I’ve been itching to buy a tablet for a while.  I’ve also been itching for another e-reader besides my droid x.  I’ve also continually talked myself out of buying a nook and rooting it.

  1. It’s a great e-reader
  2. It’s android based
  3. It can be rooted into a full tablet
  4. It’s $250 dollars (half the price of standard tablets)

However:

  1. I own a droid-x
  2. I own multiple laptops 
  3. It’s $250 dollars

When I opened it though, the inner geek in me went into immediate conflict with the responsible adult in me.  So I spent all day deciding if I should open it, or return it.  In the end, the geek prevailed and the box was open and playtime ensued.  Will loved it immediately because of some preloaded children’s books with “read to me” functionality.  Especially the story of the elephant and the crocodile.  Which he had to read again this morning:

May 27 (216)

After the kids went to bed though, Amanda and I sat down to watch a movie, while I of course watched the movie and rooted my nook at the same time.  By about midnight I had settled on and installed my image of choice.  Cyanogen mod 7, I chose this primarily because of sd expansion install and low to no risk of usage.  I do after all still enjoy the stock nook interface and features, so I didn’t want to blow it away.

May 27 (214)

May 27 (215)

Sorry for poor quality shots, dark room, camera phone, bright screen….. No Buenos.  I’ve also greatly personalized the image since this shot, this was stock image.

Second gift

Apparently my wife has been a busy woman.  Sometime back in January she began coordinating with some of my old friends back home to throw me a 30th birthday LAN Party.  Yes, this is awesome to me.  Yes, I’m that nerdy.  Yes, she raised the bar on birthday surprises and I fear I shall forever fall woefully short for her. Sad smile

May 26 (211) internet safe

Third Gift

A completely decorated 30th birthday house before I got out of bed, and a banana pudding cake….

 

May 26 (12)

May 26 (17)

May 26 (20)

May 26 (24)

May 26 (66)


So, I threw my diet a bit off yesterday.  With my birthday lunch and my banana pudding cake.  It was worth it though, now time to publish this and go ride my bike for about an hour.  God bless and have a good one!

Thanks to everyone for your birthday wishes as well (cards, etc).


Oops, almost forgot:

Keen Keen is streamlined for summer time!!!

May 24 (209)

Zoe and all her black fur is jealous!

March 27 (170)

My wife’s birthday post for me!  I’m a very blessed man indeed.

Daniel has now achieved level 30 with 0 deaths.

As I was reading my bible this past Saturday morning I came across these verses.

2 Kings 22:16-20 ESV

Thus says the Lord, Behold, I will bring disaster upon this place and upon its inhabitants, all the words of the book that the king of Judah has read. Because they have forsaken me and have made offerings to other gods, that they might provoke me to anger with all the work of their hands, therefore my wrath will be kindled against this place, and it will not be quenched. But to the king of Judah, who sent you to inquire of the Lord, thus shall you say to him, Thus says the Lord, the God of Israel: Regarding the words that you have heard, because your heart was penitent, and you humbled yourself before the Lord, when you heard how I spoke against this place and against its inhabitants, that they should become a desolation and a curse, and you have torn your clothes and wept before me, I also have heard you, declares the Lord. Therefore, behold, I will gather you to your fathers, and you shall be gathered to your grave in peace, and your eyes shall not see all the disaster that I will bring upon this place.’" And they brought back word to the king.

It’s so amazing to see Gods mercy poured out continually throughout the bible. Though he would be fully justified to lay Israel low, he preserves it, for a time, as a mercy to his repentant servant.

Showing again, God loves a contrite heart. Its humbling to realize how far gone we can be, yet find forgiveness in the presence of an infinitely righteous God.

Especially when we as fallen beings can find it so hard to forgive others of such minor trespasses…

I’ve always been a bit of an older person at heart.  I never really wanted to be the age I was, but older.  Even as I passed what most people consider the milestone ages; 16, 18, 21, I just wanted to be over 30.  Now I’m not saying 30 is old, quite the opposite these days, it tends to be when most individuals in our country begin to hit their stride.

What’s humorous to me now about the pending 30 is that, I’m not really sure why I ever cared?  My age since 25 (lower insurance premiums, yes) has been a number, and of no value to me.  The thing I see now, in looking back, is God’s grace in getting me here.  I can’t boast in anything I’ve done, I am merely a vessel.  With that, I can’t help but approach this milestone age with some regret that it took me over 26 years to find what I have now, not what I’ve established materially, but spiritually.  I’ve an eternal legacy that’s been building now for 4 years.  That’s infinitely more exciting to me than my born on date passing a 30 year mark. 

To so many people that sounds so foreign and I’m sure a little nuts.  If you are one of those people, I ask you this: What’s your legacy look like?  Surely you feel that desire to be, more?  Why is that?

Now, it’s time to evaluate PowerShell.  As of late, PowerShell has become my preferred method for scripting.  PowerShell is built on top of the .NET framework.  It uses cmd-lets (commandlets) to perform the majority of it’s command line actions.  It’s also fully integrated with WMI and the .NET Framework.  It works off of Objects, which we discussed previously with VBScript.  It shares a lot of similarities to the BASH Shell, but the object based pipe is one of the more powerful features.  Objects in the pipe remain objects through to output.  This is an important element to remember if you are already familiar to the BASH shell and find yourself working in a Windows environment now (such as myself).

There’s a lot of good reading over what PowerShell is, so I’ll go ahead and start with our code and break it down as we’ve done in the past.  We’ll be introducing CASE statements this time around, as well as arguments.  I hope you enjoy it.

 Function Get-PowerShell {

The purpose of this script is to start, stop, or restart services on a single machine or list of machines read from a file.


#Author Daniel Belcher
#Set-RemoteService start/stop/restart servicename filename.txt
Param
(
[parameter(Mandatory=$TRUE,
HelpMessage="You need a valid state entry. Start, Stop, or Restart")]
[string]$STATE,
[parameter(Mandatory=$TRUE,
HelpMessage="Please enter a valid service name. example: spooler")]
[string]$SERVICE,
[parameter(Mandatory=$TRUE)][AllowEmptyString()][string]$TARGET
) 
	Function SRS{
			PARAM ($SERVICE,$STATE,$MACHINE)
		$SOBJ = New-Object PSObject
$PING = gwmi -Query "select * from Win32_PingStatus where Address='$MACHINE'" 
    if ($PING.StatusCode -ne 0)
{$SOBJ | Add-Member -MemberType NoteProperty -Name MachineName -Value $MACHINE
 $SOBJ | Add-Member -MemberType NoteProperty -Name Status -Value "Unreachable"}
	else{
TRY{$ACTION = gwmi win32_service -filter "name like '$SERVICE'" `
					-computername "$MACHINE" -ErrorAction continue
switch ($STATE)
		   {stop{$ACTION.invokemethod("stopservice",$NULL) | out-null}
           start{$ACTION.invokemethod("startservice",$NULL) | out-null}
         restart{$ACTION.invokemethod("stopservice",$NULL) | out-null
                    start-sleep 2
                $ACTION.invokemethod("startservice",$NULL) | out-null}}

$ACTION = gwmi win32_service -filter "name like '$SERVICE'" -computername "$MACHINE"
    $SOBJ | Add-Member -MemberType NoteProperty -Name MachineName -Value $MACHINE
    $SOBJ | Add-Member -MemberType NoteProperty -Name Name -Value $ACTION.Name
    $SOBJ | Add-Member -MemberType NoteProperty -Name Status -Value $ACTION.State}
CATCH [System.UnauthorizedAccessException] 
   {$SOBJ | Add-Member -MemberType NoteProperty -Name MachineName -Value $MACHINE
    $SOBJ | Add-Member -MemberType NoteProperty -Name Status -Value "Access Denied"}
					}$SOBJ
}
Write-Host -foregroundcolor Yellow `nAttempting to $STATE $SERVICE
        if($TARGET -eq "")
        	{$TARGET = gc env:computername}
$FILE = test-path $TARGET -ErrorAction SilentlyContinue
if($FILE -eq $TRUE)
    {$READ = gc $TARGET
			ForEach ($MACHINE in $READ){
		SRS $SERVICE $STATE $MACHINE						
						   }}
else
	{
	SRS $SERVICE $STATE $TARGET
	}

Copy and paste the above code and save it as a .ps1 which is the standard file extension for PowerShell scripts.  Now, lets set our execution settings from the PowerShell command line:

Set-ExecutionPolicy remotesigned

You can now execute the script by right-clicking and run with PowerShell, or by launching it from within the shell by navigating to it’s directory and typing it’s name.

Now lets look at our interest areas:

  1. Sequence
  2. Command usage
  3. Output usage
  4. Conditional logic

Sequence:

Sequence inside PowerShell is as expected.  It’s all run inline, and requires everything called to be defined before it’s call.  Looking at the above code you will see that we call Set-RemoteService two times, and we’ve defined it at the beginning of the script.  In VBScript, or in Command, calling a sub, function, or a GOTO statement will find the appropriate section and run that code.  So being aware of how your scripts process instructions is very important to their functionality.

Now for something new, arguments.  Arguments, more or less, are user defined variables.  They are dynamic, and as such, need to be controlled to some degree.  With PowerShell you are capable of defining the variable type, and various restrictions.  This gives you incredible control and removes the potential for unforeseen errors by controlling the flow of input.

Param
(
[parameter(Mandatory=$TRUE,
HelpMessage="You need a valid state entry. Start, Stop, or Restart")]
[string]$STATE,
[parameter(Mandatory=$TRUE,
HelpMessage="Please enter a valid service name. example: spooler")]
[string]$SERVICE,
[parameter(Mandatory=$TRUE)][AllowEmptyString()]
[string]$TARGET
) 

As you can see, with the PARAM statement we are opening 3 variables for input.  They are $STATE, $SERVICE, $TARGET.  We are also insuring whatever is entered is a string value.  So that leaves us with 2 issues.  The user needs to enter something, and it needs to be useable.  So here we have provided a mandatory attribute that will prompt the user as well as a help message that the user can access for guidance on what to enter.  Now with our $TARGET variable, we want to leave it open for files, localhost, and remote machines so it will need to be a bit dynamic in nature.  There are ways to handle this in powershell with objects, but I will demonstrate conditional ways to handle it as well later on.

Command usage:

As we discussed at the beginning, PowerShell uses cmd-lets for the majority of it’s work.  It also allows you to call WMI and .NET methods and functions.  So similarly to to VBScript we can instantiate them for additional functionality.  The possibilities are plain astounding, and well beyond scope for this blog post.

Output usage:

Same as with our previous entries, all the work done is aimed at getting an appropriate output.  As such, capturing, reading, and modifying the output of all our commands is important.  How PowerShell does this, is similar to both VBScript and BASH.  You can pipe for output as input for other commands as well allowing for some very elegant one liner solutions.

Since PowerShell keeps everything in the pipe an object, your variables become immensely powerful since they are more than just stored returns from commands, but instead stored objects with invoke able methods, or property lookup, etc.  Lets evaluate how this works quickly:

$ACTION = gwmi win32_service -filter "name like '$SERVICE'" -computername "$MACHINE"

 

Here we are using a get-wmiobject Cmd-Let alias to grab a specific service, on a specific machine.  Now the variable service we are grabbing will have certain native METHODS and PROPERTIES we can leverage to either invoke or pull data.  What we need to understand is that the $ACTION variable is now an Object, not a Value.

$ACTION.invokemethod("stopservice",$NULL)

StartService and StopService are two methods belonging to Win32_Service objects.  So what we are doing here is saying essentially:

$SERVICE object, Invoke Method StopService

So everything you see at the above link is now callable, or retrievable through this variable.  Pretty cool huh?  One thing of note, if you invoke a method that changes the state of an object, it’s properties will not be refreshed until it is called again.  You will notice in the code I re-declare $ACTION after the service method invocation.

That’s because the state is changed so the property Status has changed.  Hence I couldn’t just recycle $ACTION with the $ACTION.State when building my Status property.  The object needs to be refreshed.

I use two methods for error handling in this script, one is try and catch.  The other is a in line command erroraction preference of silently continue:

TRY{$ACTION = gwmi win32_service -filter "name like '$SERVICE'"....
...$SOBJ | Add-Member -MemberType NoteProperty -Name Status -Value $ACTION.State}
CATCH [System.UnauthorizedAccessException]    
	{$SOBJ | Add-Member -MemberType NoteProperty -Name MachineName -Value $MACHINE     
	$SOBJ | Add-Member -MemberType NoteProperty -Name Status -Value "Access Denied"}

and

$FILE = test-path $TARGET -ErrorAction SilentlyContinue

The TRY and CATCH are fairly straight forward.  TRY (DO) the statement and CATCH if there is an error of [type] then do {statement}.

The –erroraction has 4 possibilities:

  • Continue
  • Inquire
  • SilentlyContinue
  • Stop

They are fairly straight forward, but all work to manage errors or exceptions in one way or another.

Conditional logic:

We’ve discussed if statements before, and as promised, I offer you a practical case statement:

                switch ($STATE){
            stop{$ACTION.invokemethod("stopservice",$NULL) | out-null}
           start{$ACTION.invokemethod("startservice",$NULL) | out-null}
         restart{$ACTION.invokemethod("stopservice",$NULL) | out-null
                    start-sleep 2
                $ACTION.invokemethod("startservice",$NULL) | out-null}                
                                }

The syntax says switch, but the methodology is the same.  All that is happening is we are saying if $STATE = “Stop” or “Start” or “Restart” do this.  Either 3 separate if statements, or 1 case statement.  Fairly efficient manner for handling complex conditions that hinge around one variable.

So what does this PowerShell script do?

It begins by declaring 3 variables that are to be string values.  All 3 as Mandatory, while one is allowed to be an empty string.

Next it builds a function to be reused through the remainder of the script “SRS”. In this function we create a powershell object for storing property data. A ping test is done using a WQL to determine if the machine is online, or if the name is even valid. (the reason we do this, is that it’s increasingly faster to ping for response than to wait for a timeout to occur on a RPC request).

If the machine successfully pings it moves on to declare the $ACTION variable object for use in the Set-RemoteService function. We then check the $STATE string against our SWITCH (CASE) statement and perform the appropriate method.

Reset the $ACTION variable and begin creating and storing note properties to our $SOBJ for reporting.  If either the ping fails, or an unauthorized access error occurs we generate a coresponding note property to the sobj for reporting, and then the function writes the objects properties to the console, then we close the function.

Now the script writes to host a message confirming the attempted status service, ee evaluate the 3rd variable $TARGET and set it’s value to the local machines name if the value is an empty string.

        if($TARGET -eq "")
        	{$TARGET = gc env:computername }

 

Check to see if that $TARGET is a file, if it is we read it and for each item in the file we pass it to our SRS function.  If it wasn’t a file, it does the same thing without a for each statement.

}


So you want a little more?

I’m going to quickly show you how you can integrate this script, into a profile function.  It’s exceptionally easy, and I recommend it for scripts you’ve built that you find invaluable for day to day use.

Here goes the modified code:

Function Set-RemoteService{
Param
(
[parameter(Mandatory=$TRUE,
HelpMessage="You need a valid state entry. Start, Stop, or Restart")]
[string]$STATE,
[parameter(Mandatory=$TRUE,
HelpMessage="Please enter a valid service name. example: spooler")]
[string]$SERVICE,
[parameter(Mandatory=$TRUE)][AllowEmptyString()][string]$TARGET
) 
	Function SRS{
			PARAM ($SERVICE,$STATE,$MACHINE)
		$SOBJ = New-Object PSObject
$PING = gwmi -Query "select * from Win32_PingStatus where Address='$MACHINE'" 
    if ($PING.StatusCode -ne 0)
{$SOBJ | Add-Member -MemberType NoteProperty -Name MachineName -Value $MACHINE
 $SOBJ | Add-Member -MemberType NoteProperty -Name Status -Value "Unreachable"}
	else{
TRY{$ACTION = gwmi win32_service -filter "name like '$SERVICE'" `
					-computername "$MACHINE" -ErrorAction continue
switch ($STATE)
		   {stop{$ACTION.invokemethod("stopservice",$NULL) | out-null}
           start{$ACTION.invokemethod("startservice",$NULL) | out-null}
         restart{$ACTION.invokemethod("stopservice",$NULL) | out-null
                    start-sleep 2
                $ACTION.invokemethod("startservice",$NULL) | out-null}}

$ACTION = gwmi win32_service -filter "name like '$SERVICE'" -computername "$MACHINE"
    $SOBJ | Add-Member -MemberType NoteProperty -Name MachineName -Value $MACHINE
    $SOBJ | Add-Member -MemberType NoteProperty -Name Name -Value $ACTION.Name
    $SOBJ | Add-Member -MemberType NoteProperty -Name Status -Value $ACTION.State}
CATCH [System.UnauthorizedAccessException] 
   {$SOBJ | Add-Member -MemberType NoteProperty -Name MachineName -Value $MACHINE
    $SOBJ | Add-Member -MemberType NoteProperty -Name Status -Value "Access Denied"}
					}$SOBJ
}
Write-Host -foregroundcolor Yellow `nAttempting to $STATE $SERVICE
        if($TARGET -eq "")
        	{$TARGET = gc env:computername}
$FILE = test-path $TARGET -ErrorAction SilentlyContinue
if($FILE -eq $TRUE)
    {$READ = gc $TARGET
			ForEach ($MACHINE in $READ){
			SRS $SERVICE $STATE $MACHINE						
						   }}
else 
	{
	SRS $SERVICE $STATE $TARGET
	}
}

We’ve enclosed the entire thing into a Function statement now, and redefined the internal function.  The reason for this was, well, I prefer to stick with cmd-let naming patterns.  I’d rather call set-remoteservice at the command line.

Now, we need to build our profile, from inside PowerShell, at the command line type:

notepad.exe $PROFILE

Now paste the above code and save it.  If you are inside ISE press F5 to run the script and update your profile, or if you are in the standard shell type:

powershell

This will start a new shell instance inside your previous shell with the updated profile.

Be mindful, PowerShell and PowerShell ISE have two separate profiles.  So if you perform this in ISE the standard shell won’t receive the update and vice versa.


That does it for my stick to the script series.  I hope you’ve learned a lot regarding scripts through this and it’s shed some light onto what scripting is and de-mystified it for you.

I will continue to post scripts for various things over time, as well as neat tricks as I learn them so I wouldn’t say this is truly the end.

Editors:

If you intend to do a lot of scripting, I recommend you grab yourself a steady editor.  Preferably one with configurable highlighters.  Below are a list of a few free and premium editors I recommend.  I’ll start with the freebies:

  • Context – A nice, windows based, free editor (my usual windows editor). Configurable highlighters, comparison tool, and configurable execution keys.  All the basic needs of a script writer.  Minus integrated libraries.  I believe development has all but stopped since 09, so this might not be the best editor to stick to.
  • Emacs – Extremely powerful development environment built for OSS, but with Windows versions.  This is more than a simple editor, it’s a Swiss army knife.  It will require a bit of a learning curve to begin using it but is worth it in the end.
  • VIM – My preferred editor in Linux, switchable modes, highlighters, line numbers, split views, compares, command line style editing.  Like emacs, it’s extremely powerful, and has a bit of a learning curve.  I prefer VIM, but Emacs is far more extensible, just fyi.
  • NotePad++ – A really nice OSS editor for Windows.  I should probably start using this over Context, but I’ve already spent so much time with Context configuring it, I’ve become extremely comfortable with it.  I’d recommend this editor to any novice windows scripter.
  • PowerGUI – Both a free, and paid edition.  I recommend this editor for PowerShell whole heartedly because of it’s syntax and object recognition tools.  If you are going to do a lot of work with PowerShell, I recommend using this editor for it.
  • PSEdit – Included with the PowerShell ISE.  It’s the standard PowerShell editor.

Premium:

If you are interested in learning more:

Stick to the Script Parts 1 – 4:

  1. Stick to the Script…
  2. Stick to the script #!/BIN/BASH…
  3. Stick to the script CreateObject(“Wscript.Shell”)…
  4. Stick to the Script PS C:> PowerShell …

I’ve honestly been trying to post my final part to the “stick to the script” series.  However those actions have been soundly thwarted by an abundance of work, and a new workout regiment.  I hope to have it up and syndicated to myitforum before the weekend is over.

I’ve also built a nice sccm client install script, and thanks to John Marcum, I’ve built a nice remote cm wmi repair tool in powershell as well.

So stay tuned as I plan to start releasing those scripts after scrubbing them.

So my wife and I have been waiting for today.

No, it’s not a holiday or anything special like that.  Today is the day that we take our sweet little girl Maggie to her occupational therapist for review.  This is the day we find out the extent of her trauma from birth.  This is the day that we cling to God the tightest.

We are fearful of what we might find out, we are excited about being taught how best to work with our beautiful little girl.  In the end, God is enough.  We pray that what afflicts our daughter is manageable.  That her quality of life won’t be jeopardized by the news we find out today.  We know that all things to the good of those who love him and are called according to his purpose.  We know that His grace is sufficient.  We know that he is our strength and our portion forever.  So even though our flesh or our children or our jobs or our world may fail us.  He will not.

God will be glorified in no matter what comes from today, I pray that our daughter is healed for his name sake.  That we might proclaim his miraculous work through our daughter.

If you are reading this, please take some time today to pray for us. 

This is so much bigger than us.

 

-Daniel, a loving father


So it’s my 6 year anniversary with my beautiful and loving wife.  My helper, my bride, my best friend, my lover, and my rib.

Then the man said,

“This at last is bone of my bones and flesh of my flesh; she shall be called Woman, because she was taken out of Man.”

Therefore a man shall leave his father and his mother and hold fast to his wife, and they shall become one flesh. And the man and his wife were both naked and were not ashamed. -Genesis 2:23-25

God has given me more than I could ever have hoped or prayed for in a mate, and I praise him for that.  Through every trial we’ve been through in the past year and are going through this year, I couldn’t imagine anyone better fit to keep me grounded in faith and love than my dear sweet Amanda.

This anniversary was a bit lack luster, we spent most of it doing stuff with our kids as opposed to focusing on us.  There is good reason for that, but I still want to take the time to at least voice my undying love for the woman whom I left behind my mother and father for and become one flesh with.

Happy Anniversary, may we reach 60!