Skip navigation

Category Archives: Technology

Discussion on any and all tech related items. New tech, tech usage, etc.

On a more regular basis I’d like to keep a stream of technical write ups, gaming news, theological thoughts, and or general “what’s going ons” with me and my family.  However with a work trip to Houston last week and general slap busy nature of my work since returning home; I’ve not had any time to collect some thoughts and formulate them into a blog post.  I want to hit some high points, and perhaps elaborate on them more in future posts.

High point #1 Samba DC

Ok, so people who have known me for any extended amount of time (from the age of 16 to 30) knows that I’m a Linux fan.  My work and lively hood mind you thrive around a Microsoft world, but I will never sell Linux short, nor fail to marvel at the amazing things that a thriving community of passionate individuals can create.  I also maintain a Linux server out of my home to manage DNS, DHCP, VOIP (TeamSpeak) and File sharing (NFS, iSCSI, and SMB).  I will also, on occasion, bring up outward facing game servers.  Just recently I decided to convert that server into a SAMBA DC for my, primarily, Windows 7 environment at home.

I run CentOS as my server distribution, which is a downstream of RHEL.  I’m running Samba version 3.5.4, at the time of this writing 3.6 is the latest stable release but didn’t offer enough improvements for me to go outside of my natively distributed yum version.

Also, aside from a few changes to the registry and local security policy that had to be made on the client side of the machines, the migration was fairly painless.

The first change resolves the issue of Windows 7 being able to find the domain for insertion, and the security policy solves the issue of Domain Trust at login.  It’s also wise to disable the password reset of the machine to DC to avoid potential relationship issues.  I’d not seen this issue myself, but until I see a confirmation it’s resolved (supposedly coming in samba 4) I’ll err to the side of caution.

My next step will be to integrate Open LDAP functionality into the DC, and an Apache http server.  I assume these will be fairly painless projects, but for risk of breaking my current domain environment I’ll need to wait till I have the time to deal with a potential ldap migration failure.  I also don’t have a strong enough list of pros for it since this is just a home network.  Mind you it’s more sophisticated than the average home network, it just seems a bit over engineered.  As for the Apache server, I really want to get back into some web development so I’d like the internal server for development purposes….

 

service httpd start

Ok, so now I’m running an Apache server off my server as well.  Linux is so hard.

 


 

High point #2 Admin Studio 10

So I was in Houston last week.  I’m now “officially” trained to use Admin Studio 10 for package (msi, app-v, xenapp, and thinapp) development, repackaging, and migration.

So what does that mean?

Well as most of you know I work with a product from Microsoft called SCCM.  One of the primary features of SCCM is application deployment.

So what is application deployment?

Simply put, it’s installing applications to multiple machines over a network.

Ok, I think I see.  So why would you need to do package development to deploy packages?

Well, you don’t have to.  One could feasibly shoehorn an installer given by a vendor, but ideally you want to build out a standardized installer or load for your company.  For us that means I’ll be building MSIs, MSTs, and App-v packages.  As well as isolating application installs that might otherwise break functionality of OTHER applications they share hard drive space with.

Wait, what?  Isolate, break, huh?

Almost all applications rely on libraries.  Think of them as a set of shared instructions that applications go to when asked what to do.  Well in most cases these libraries are shared by multiple applications.  And, sometimes one application wants a vanilla library, and another wants a chocolate.  Well these apps will fight, and one of them will win and another one will lose.  By isolating them I can give them what they want so they don’t break the system, or each other.

Our company will also leverage App-v packages which are essentially virtualized installs of these applications that, although they run locally on the machine, they are actually virtualized (or encapsulated) and are separate from the actual operating system.  Xenapp and Thinapp do the same thing.  I’m particularly excited about application virtualization, it can come with a bit of overhead, but it’s nice and contained.

Ok, I stopped caring somewhere around chocolate and vanilla.

Yea I figured as much.  Either way, it is a tangible notch to my hard skill set and I’m glad that I was able to get it done.

 


 

 High point #3 Gospel in Life

What does a Gospel centered life look like?

What does it mean to be in the world but not of the world?

Is the Gospel as narrow minded to culture as people often proclaim it to be?

What does a Gospel centered community look like?

These are part of the current bible study I’m involved in with my brothers and sisters in Christ called Gospel in Life by Timothy Keller. It’s a great study that forces you to take a look at your heart, your life, and your community and compare it to what and how it is defined in the Gospel. I would recommend this study to anyone who is a believer. Even if the information isn’t new to you, as most of it hasn’t been for me, it’s still food for the soul. A reminder of the higher purpose we are called to as Christians.

Truthfully, I’d encourage non-believers as well to read this study. If for nothing else, than to hold Christians accountable to the teachings that we claim to believe.

 


 

High Point #4 Ignoring my Family

I’ve taken way to long to blog this, and my wife has informed me that I should blog about how I’ve ignored my family, to blog.

When she’s right she’s right.  Thank God for her gentle reminders.

 


As a Systems Engineer/SCCM Administrator I spend a lot of time parsing through data, and assisting support technicians in tracking down failing assets.  Now mind you, I have plenty of reports that give me the information I need to identify the machine and users and techs responsible etc, but what happens when I get a random list of employee names from a project manager that has 0 access to user ids or asset numbers for machines?  Well, I have to find that information, then spend time later pointing them to resources I’ve made available for them; but that’s another topic….

Anyway, I face both problems, I’ll receive a list of userids or usernames and have to resolve them one against another.  Well thanks to powershell I’m able to do so quickly and easily through profile functions.  Now, I’ll explain the benefits of profile functions after the code below:

 


Import-Module activedirectory

#——————————————————————–
Function Get-UserName {
[CmdletBinding()]

PARAM($USERID)
Get-ADUser $USERID | select name
}
Set-Alias gun Get-UserName
#——————————————————————–
Function Get-Userid {
[CmdletBinding()]
PARAM([string]$NAME)
$NAME = $NAME + “*”
    Get-ADUser -Filter {Name -like $NAME} | select samaccountname,name
}
Set-Alias guid Get-Userid
#——————————————————————–

 


 How do I use profile functions?!?

Powershell, much like the BASH shell in Unix/Linux, has a profile “script” so to speak at startup.  There is a global one found at:

  • %WinDir%\System32\WindowsPowerShell\v1.0\Profile.ps1
  • %WinDir%\System32\WindowsPowerShell\v1.0\Microsoft.PowerShell_Profile.ps1
  • %WinDir%\System32\WindowsPowerShell\v1.0\Microsoft.PowerShellISE_Profile.ps1

The same filename syntax is used for the user profile versions:

  • %UserProfile%\My Documents\WindowsPowerShell\Profile.ps1
  • %UserProfile%\My Documents\WindowsPowerShell\Microsoft.PowerShell_Profile.ps1
  • %UserProfile%\My Documents\WindowsPowerShell\Microsoft.PowerShellISE_Profile.ps1

See a pattern?  Simple enough right?  None of these profiles exist by default though, they must be created.  The names are fairly indicative of what they control, but here’s a breakdown:

  • Profile.ps1
    • This governs startup of both the standard powershell, and the ISE.
  • Microsoft.PowerShell_Profile.ps1
    • This governs startup of the standard powershell console only.
  • Microsoft.PowerShellISE_Profile.ps1
    • This governs startup of the ISE powershell console only.

Simple enough right?  Now, for the sake of simplicity, lets build a current user version of the profile.ps1 and save the above code to it.  Make sure you’ve installed the activedirectory cmdlet module provided with windows 7. Now launch powershell and viola you should now have the cmdlets:

  • Get-UserName
  • Get-UserID

and their aliases:

  • GUN
  • GUID

Ok, now what?

Here’s the thing about profile functions.  You can treat them like cmd-lets now.  That also means that you can script against them.  Consider them a static variable for every powershell session that you have configured with this profile.

Pretty cool huh?  One of the most powerful features of the shell is it’s configurability, and profile functions and aliases are the tip of that spear.

In the case of user name capture, or id capture, I’m but a simple gc and for-each statement away from processing the list given to me.

I hope this helps broaden your practical understanding of profiles, and gets your creative juices flowing for building your own administrative tool kits.  Happy scripting.

I haven’t written a scripting post in a while, but I’ve wanted to.  So in keeping with the spirit of my stick to the script posts lets look at something that is common among all scripting languages (even if the syntax isn’t).

Let’s talk about strings…….

 kitty-yarn

Awwww, but no.  These kind of strings.  In the case of scripting, I think the best way to think about it is, text, what you are reading or able to read.  They aren’t used mathematically (usually), but can and will be a huge component in your scripting.  Especially when automating things around a desktop or server environment.

Oh really?  Yes, really.  General uses for strings in a script are:

  • User messages
  • Reporting or logging
  • Comparisons
  • Explicit paths
  • Application execution
  • Conditionals

Ok, so maybe that list doesn’t look that impressive, but when you consider how much of that is done within a script, it becomes obvious the importance of string values to scripting.  It’s also important to recognize that in certain scripting environments, it’s important to define a string value as such so that it can be properly used. 

(Powershell for instance, requires you to properly define a value type to use the relevant functions… but I’m getting ahead of myself.)

So wait?  There are more than strings in a script?  Yes; Strings, Integers, and Booleans are your standard value types. Integers are numbers (math!) and Booleans are True or False.  So given those value types, perhaps it is a bit more obvious how frequently you will use string values?

So lets get into some sample code and evaluate strings some shall we?


VBScript:

strTest = "Hey, I'm a string value"

wscript.echo strTest
'Shows the string value
wscript.echo strTest&", and I've been concatenated to the value."
'& operator joins values
wscript.echo lcase(strTest)
'Lower case
wscript.echo ucase(strTest)
'Upper case
wscript.echo strReverse(strTest)
'Reverses the string
wscript.echo len(strTest)
'Gives the total length of a string
wscript.echo mid(strTest,10,8)
'Returns fix number of characters in string
wscript.echo left(strTest,11)
'11 chars from the left
wscript.echo right(strTest,13)
'13 chars from the right
'----------------------------------------------------------------
wscript.echo inStr(strTest,"a")
'Returns position of string from left to right
wscript.echo inStrRev(strTest,"a")
'Returns position of string from right to left
'----------------------------------------------------------------
a = split(strTest)
'Splits strTest by it's spaces
for each item in a
    wscript.echo item
   'echoes each dimension from the split array
next

wscript.echo a(3)&" "&a(4)

'echoes the split arrays dimensions 3 and 4
'---------------------------------------------------------------

strReturn=inputbox("Here, you try!")

if strReturn = "" then
   wscript.echo "Fine, don't play along"
else
    wscript.echo "So you said: "&trim(ucase(strReturn))&vbcrlf _
    &"Sheesh, no need to shout!"
end if
'---------------------------------------------------------------


Running the above script will give you a better understanding of what I’m about to explain.  I wanted to show some common functions in vbscript (syntax is different but these will be universal functions you will use).  The above are common string manipulation tools

 

Code explained… line by line

First we are defining our string to a variable strTest.  Now “in the wild” as it were, this string could be pulled from an object property, read from a file, registry, user input, output from another application, etc.  It’s best to define a string to a variable though, no matter the method for input.  This of course is the most direct way to do it for our example

Now we begin with the simplest string usage, output.

Now we raise the stakes a bit by joining an additional string value to our current strTest.  This action is known as concatenation.  This is a very common thing with string usage and manipulation.  Building complex values/messages/logs from various predefined and/or dynamically pulled string values.

Our next two examples have to do with manipulating case between upper and lower.  This is fairly self explanatory, and in the interest of string comparisons it’s usually a good practice (and often necessary) to force a case set, especially if the comparison function is case sensitive.

String reversal, this may not seem important initially, but makes a huge difference when you are forced to chop strings up.  The ability to reverse a string can go a long way for string chopping.  Especially if you are dealing with filenames.

The length function is another that may seem arbitrary to some, but allows for great flexibility as well in chopping up strings such as file names.  If you have a fixed number of characters to remove it’s sometimes simpler then splitting the string.  (so I wasn’t completely honest about the math stuff and strings)

Mid, Left, and Right.  These 3 can be used in conjunction with length to return a fixed number of characters from the left right, or middle (specified) of a string.  Here’s a quick easy example:

test="I am 18 chars long"
wscript.echo test
count=len(test)-4
wscript.echo right(test,count)

Very simply, we take the total length of Test and subtract it by 4, then return the sum of remaining characters from right to left of the original string.  In this example we, had a fixed value to subtract, be mindful you could use the length value of multiple strings to achieve the same type of results.

Now, InStr and InStrRev, or “In String” and “In String Reverse”.  These two functions make for great conditionals.  They, along with strComp, are excellent for determining like strings and taking action.  Especially when parsing through files and directories looking for specific returns. 

One of my favorites, especially in PowerShell, split.  Split takes a string, looks for a delimiter (space by default) and breaks the string up into an array.  Why do I like it so much?  Put simply, it allows you to quickly whittle down long path names into a single filename.  It also allows you to quickly and efficiently modify lists of data into manageable formats.  And last but not least, it can easily turn files like csv’s into an array for manipulation.

Finally, user input.  This is pretty self explanatory.  Prompt for input, receive and control input, use input.


In PowerShell, string functions are called like this:

$a=”This is a string value”

$a.ToString()

$a.ToUpper()

$a.ToLower()

$a.Replace(“a “,”my “)

$a.split(“ “)

$a.contains(“string”)

$a.StartsWith(“t”)

$a.EndsWith(“e”)

$a.Length

$a.CompareTo(“this is a string value”)

$a.Length.Equals(22)

$a.CharArray()

$a.PadLeft(“30”)

$a.PadRight(“30”)

$a.Trim()

$a.TrimEnd()

$a.TrimStart()

Given the previous examples in vbscript, you should be able to easily adapt your knowledge to using these in PowerShell.  The idea and purpose is still the same, again, the syntax is just different.


String manipulation inside Bash is, admitedly, a bit more convoluted so I won’t be touching on it in this post.  However I’d highly recommend an online source like: Mendel Cooper’s guide.  Again, the methodology will still be fairly the same, but the syntax will differ.  The largest issue with Bash is the myriad of ways of performing the string manipulation.

 

Anyway, I hope this has been informative for you.  Good luck, and happy scripting!

So as some of you may or may not know.  My wife is conducting a 365 picture project this year.  What’s a 365 picture project?  Essentially take a pic of you, or something in your life for each day of the year and compile it all together at the end of the year to sort of journal everything.  It’s, as you can imagine, a lot of pictures being taken a day.  I would say on average she has 5 to 10 pictures taken a day.  Realistically speaking, some days it’s about 2, others it’s near 30 or more. 

 

Ok, great, why are you telling me this? 

 

Well, I’m glad you asked.  She would spend a lot of time sorting, renaming, and organizing them.  I’ve been telling her a long time “just automate it” which is something I tell her about almost everything she does that’s repetitive.  Well finally after a long night or sorting through some 100+ photos she called me on it, and had me write her a script to rename all the files for her.  I also had a chance to get to show her a bit of that “computer stuff” I do everyday at work. Also, it’s been a while since I’ve done a scripting post, so I’m using this. 🙂

I figured I would go with powershell since I would have (easier) access to the .NET System.IO.DirectoryInfo class.  One of the things my wife loves is chronological accuracy, so pulling a timestamp from the image as part of its name seemed like a good idea.  She already had a routine where she copied them from her camera to an appropriate folder so specific file information was the only real concern here so this was going to be a very simple script.  Below is the code:

 


PARAM([string]$FOLDER)
$ErrorActionPreference = "silentlycontinue"
if($FOLDER -eq "")
    {$FOLDER = Read-Host "Path to picture folder?"}
    $LIST = Get-ChildItem "$FOLDER\*" -Exclude *ps1 `
    -Include *jpg,*tiff,*jpeg,*gif,*bmp,*txt
            $X = 0
    ForEach($OBJECT in $LIST)
        {$EXTENSION = $OBJECT.ToString().Split("\") | Select -Last 1
            $EXTENSION = $EXTENSION.Split(".") | Select-Object -Last 1
              $FILEINFO = New-Object System.IO.DirectoryInfo($OBJECT)
                $NAME = $FILEINFO.LastWriteTime.GetDateTimeFormats() `
                | Select-Object -Index 99
                    $NAME = "$($NAME) ($($X)).$($EXTENSION)"
                        Write-Output $NAME
            Rename-Item -Path "$OBJECT" $NAME
            $X = $X+1
            }       


So what’s happening?

First we run this script, either by launching it directly, or by launching it on a command line followed by the folder where our pictures reside. The folder path is our only variable here, if one isn’t entered at the start of execution, it will prompt the user for one.

Now the script will build an object list of everything inside the folder taking special care to exclude any potential powershell scripts in the directory to the $LIST variable.  I also built it to specifically include image file types (I didn’t want to rename some random non-picture files she might be storing in the directory (well, and txt for my testing purposes)). 

Now we define an integer value to $X so we can enumerate it for a counter during our ForEach loop, which we begin next.

For each file in $LIST we:

  1. Grab the extension for the file to variable $EXTENSION
  2. Retrieve the last write time of the file and store it as $NAME
  3. Set $NAME to $NAME + $X + $EXTENSION
  4. Write the final $NAME to console
  5. Rename the item to $NAME
  6. Enumerate $X by 1
  7. Loop

The outcome?

 

I showed her the way it renamed a series of text files I had placed in a test folder on my laptop.  At first, I received a rather dismissive “Oh, that’s good babe” however after I sat down at her desk and showed her the bad boy in action renaming another folder of 100 or so images in seconds, the sly grin found it’s way across her face.  The joy of automation.  The kind you can only get when you see something so small perform such a mind numbing laborious task for you.

She’s not quite ready to learn scripting, but at least now her eyes are open to other possibilities for automated solutions in her everyday computing.  And as a stay at home mother of 2, I’m more than willing to help her streamline all her recreational and productive time at the keyboard.  She is after all, my number 1 customer ;).

So this article was just posted.  I read it, and about cried.

http://tech.slashdot.org/story/11/06/06/2222226/How-To-Succeed-In-IT-Without-Really-Trying

What they are discussing here is something that truly geats at me in respect to my industry.  I’m certain its true in almost every area.  People can’t lead what they can’t understand.

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)

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.


#Service State Changer Script
#Author: Daniel Belcher

#Syntax:
#    .\set-remoteservice.ps1 stop spooler laptopname

PARAM([string]$STATE,[string]$SERVICE,[string]$TARGET)
$ErrorActionPreference = "silentlycontinue"
Function Set-RemoteService{
SWITCH($STATE){
        "Start"
            {$SET.Start()
                Write-Output "`nService: $($SERVICE.ToUpper()) `nStatus: Starting`n"}
       "Stop"
            {$SET.Stop()
                Write-Output "`nService: $($SERVICE.ToUpper()) `nStatus: Stopping`n"}
        "Restart"
            {$SET.Stop()
        Start-Sleep -Seconds 1
             $SET.Start()
                 Write-Output "`nService: $($SERVICE.ToUpper()) `nStatus: Restarting`n"}
             }

if ($STATE -ne "Start"){if  ($STATE -ne "Stop"){if ($STATE -ne "Restart"){
    Write-Output = "Invalid service state entered`n";Break}}}

                         }
if ($SERVICE -eq "")
    {$SERVICE = Read-Host "Please enter a valid service name"}
    if ($STATE -eq "")
        {$STATE = Read-Host "You need a valid state entry. Start, Stop, or Restart"}
        if ($TARGET -eq "")
            {$TARGET = $ENV:COMPUTERNAME}       
    $FILECHECK = Test-Path $TARGET
        if ($FILECHECK -eq $TRUE){
            $READ = gc $TARGET
                ForEach ($ITEM in $READ)     {
            $PING = gwmi -Query "select * from Win32_PingStatus where Address=’$ITEM’"
    if ($PING.StatusCode -ne 0)
        {Write-Output “$ITEM not found online, or invalid hostname.`n"}
    else
        {$SET = (Get-Service $SERVICE -ComputerName $ITEM)
                        Set-RemoteService
                    Start-Sleep -Seconds 1   
 
$STATUS = (Get-Service $SERVICE.ToUpper() -ComputerName $ITEM.ToUpper()).Status
         Write-Output = "Machine: $ITEM`nService: $SERVICE`nStatus: $STATUS`n"
}
                                }
                            }   
        else
            {$PING = gwmi -Query "select * from Win32_PingStatus where Address=’$TARGET’"
    if ($PING.StatusCode -ne 0)
        {Write-Output "$TARGET not found online, or invalid hostname.";
                            break}
            $SET = (Get-Service $SERVICE -ComputerName $TARGET)
                        Set-RemoteService
                Start-Sleep -Seconds 1  

$STATUS = (Get-Service $SERVICE.ToUpper() -ComputerName $TARGET.ToUpper()).Status
        Write-Output = "Machine: $TARGET`nService: $SERVICE`nStatus: $STATUS`n"
}


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 unrestricted

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 are, more or less, are user defined variables.  They are dynamic, and as such, need to be controlled to some degree.  So a fair amount of the script sequence is spent insuring that the variables passed are useable.  With PowerShell you are capable of defining the variable type.  This gives you incredible control and removes one more potential for unforeseen errors.

PARAM([string]$STATE,[string]$SERVICE,[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.  We will discuss this more in our conditional logic.

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:

$SET = (Get-Service $SERVICE -ComputerName $TARGET)

Here we are using a Get-Service Cmd-Let 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 $SET variable is now an Object, not a Value.

$SET.Start()

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

$SERVICE object, Invoke Method Start

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 declare a $STATUS variable.

$STATUS = (Get-Service $SERVICE.ToUpper() -ComputerName $TARGET.ToUpper()).Status

Because the state is changed, the property Status is changed.  Hence I couldn’t just recycle $SET with the $SET.Status.  The object needs to be refreshed. (Don’t be confused by the .ToUpper(), these are just native PowerShell methods for string management.  In this case UpperCase)

Now the $STATUS variable could just be considered a value.  Since it is in fact a capture of the property value.  Starting to make better sense now?

I don’t really utilize any direct error handling inside this script outside of the $erroractionpreference value.

$ErrorActionPreference = "silentlycontinue"

This just means if I hit an error, move on to the next statement, and do so without any visible output to the user.

Conditional logic:

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

SWITCH($STATE){
"Start"
{$SET.Start()
Write-Output "`nService: $($SERVICE.ToUpper()) `nStatus: Starting"}
"Stop"
{$SET.Stop()
Write-Output "`nService: $($SERVICE.ToUpper()) `nStatus: Stopping"}
"Restart"
{$SET.Stop()
Start-Sleep -Seconds 1
$SET.Start()
Write-Output "`nService: $($SERVICE.ToUpper()) `nStatus: Restarting"}
}

The syntax says switch, but the methodology is the same.  All that is happening is we are saying if $STATE = “Start” or “Stop” 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.

Then it tells the shell to remain silent and continue on errors.

Next it builds a function to be reused through the remainder of the script

Function Set-RemoteService{

This is where our case statement is built and stored.  We also have an additional conditional statement in there to insure that one of the 3 pre-defined strings were typed correctly.  Now we perform an if statement to determine that the variables were defined at execution, if not then we prompt the user for input.  If $TARGET is empty we simply define it as $ENV:COMPUTERNAME, which is equivalent to LOCALHOST (just a bit more elegant).

Now it performs a quick check to determine if the $TARGET passed was a file or simply a name.  If it was a file, the file is opened and assigned to the $READ variable where a for each statement is run against it.

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 $SET variable object for use in the Set-RemoteService function.  Then it executes the function, then a 1 second pause, and then builds an object property variable that is used in a console message to the user notifying them the state of the service after the action.

If it wasn’t a file, it does the same thing without a ForEach 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([string]$STATE,[string]$SERVICE,[string]$TARGET)
$ErrorActionPreference = "silentlycontinue"
Function SRS{
SWITCH($STATE){
                       "Start"
                           {$SET.Start()
                                  Write-Output "`nService: $($SERVICE.ToUpper()) `nStatus: Starting`n"}
                       "Stop"
                           {$SET.Stop()
                                  Write-Output "`nService: $($SERVICE.ToUpper()) `nStatus: Stopping`n"}
                       "Restart"
                           {$SET.Stop()
                     Start-Sleep -Seconds 1
                            $SET.Start()
                                  Write-Output "`nService: $($SERVICE.ToUpper()) `nStatus: Restarting`n"}
                           }

if ($STATE -ne "Start"){if ($STATE -ne "Stop"){if ($STATE -ne "Restart"){
      Write-Output = "Invalid service state entered`n";Break}}}

                          }
if ($SERVICE -eq "")
    {$SERVICE = Read-Host "Please enter a valid service name"}
    if ($STATE -eq "")
        {$STATE = Read-Host "You need a valid state entry. Start, Stop, or Restart"}
       if ($TARGET -eq "")
           {$TARGET = $ENV:COMPUTERNAME
      $FILECHECK = Test-Path $TARGET
             if ($FILECHECK -eq $TRUE){
                 $READ = gc $TARGET
                           ForEach ($ITEM in $READ) {
           $PING = gwmi -Query "select * from Win32_PingStatus where Address=’$ITEM’"
    if ($PING.StatusCode -ne 0)
       {Write-Output “$ITEM not found online, or invalid hostname.`n"}
   else
       {$SET = (Get-Service $SERVICE -ComputerName $ITEM)
                              SRS
                          Start-Sleep -Seconds 1
$STATUS = (Get-Service $SERVICE.ToUpper() -ComputerName $ITEM.ToUpper()).Status
             Write-Output = "Machine: $ITEM`nService: $SERVICE`nStatus: $STATUS`n"
}
                                                       }
                                               }
             else
                   {$PING = gwmi -Query "select * from Win32_PingStatus where Address=’$TARGET’"
         if ($PING.StatusCode -ne 0)
              {Write-Output "$TARGET not found online, or invalid hostname.";
                                                  break}
                    $SET = (Get-Service $SERVICE -ComputerName $TARGET)
                                   SRS
                        Start-Sleep -Seconds 1

$STATUS = (Get-Service $SERVICE.ToUpper() -ComputerName $TARGET.ToUpper()).Status
             Write-Output = "Machine: $TARGET`nService: $SERVICE`nStatus: $STATUS`n"
}

}

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 I’ve been waiting for Brink to release for some time now.  Both my brother and I had it on pre-order and were ready to go day of release.  The day came, we grabbed it, installed it, then went to play it online together…

Now, I’ve read a lot of what people have been saying about this game and I have to agree, it fell flat, now we found a few games last night where he and I got to really throw down and have a blast, but the responsiveness was barely tolerable.  Anyone who remembers the old quake days before QWC and client detection, it was like that.

Visually the game looks great, well, most of the time.  I am still having anomalies with texture and mapping loads.  I’ve also had some bizarre issues of not being able to connect to my own game server…. yea, go figure that one out.

Overall the customization, and the play mechanics, I actually enjoy.  The slide tackling, and melee knockdowns.  The parkour (although at first rough) has really proven itself as a great new play style option.  However, if this multiplayer synching issue doesn’t get solved, I don’t think I’m going to see my money’s worth out of this title.

(Just spoke with my brother, he’s been on playing all morning, he told me that it appears to be running smooth today.)

So I’ll follow up on this, perhaps all is not lost!

So in the world of SCCM there are tons of moving parts and components.  I want to take some time to focus on some common issues with client installation and communication issues, as well as a couple of tools that make troubleshooting infinitely easier.


Tools

First up I want to list 3 of the primary tools I use for client side troubleshooting.

  1. Trace32 Log Reader
  2. SCCM Client Center
  3. JSandys CM Startup Script

Now the first item on that list, trace32 is by far the most valuable tool to the SCCM administrator outside of the console itself, perhaps even more so than the console.  It allows filtering, highlighting, real time updates, and just generally makes the logs readable.

SCCM Client Center, this tool attaches to the cm WMI Namespace and allows for nearly full control of the client on the target machine.  In terms of remediation, or even testing, there is no reason this tool shouldn’t be installed.

Config Manager Startup Script by Jason Sandys.  This script is easily configured for implementation and has fairly rich logging power for a vbscript, it’s also lighter weight than some of the other health scripts.  I highly recommend using this for maintaining client integrity, as well as offering an installer tool for the CM agent by secondary or third parties.


The Client

First, lets start with identifying the clients existence on the local machine.

Here’s where to look:

  • Control Panel > Configuration Manager (this is one of the quickest methods)
  • Task Manager (ctrl+shift+esc) > Processes > CcmExec.exe
  • Task Manager > Services > CcmExec
  • Control Panel > Admin Tools > Services > SMS Agent Host
  • c:\windows\system32\ccm (32bit)
  • c:\windows\syswow64\ccm (64bit)
  • HKLM\SOFTWARE\Microsoft\SMS\Mobile Client\Product Version (32bit)
  • HKLM\SOFTWARE\Wow6432Node\Microsoft\SMS\Mobile Client\Product Version (64bit)

This is a list of the primary locations to check for the presence of the client, it’s also useful for finding methods to script around identifying them.

 

The Client’s Jobs

Now lets discuss what the client does.  First lets recognize that the client is just a dictator for the most case, it tells multiple windows services what to do to complete specific tasks.  Until we need to break down what services do things specifically lets just treat the client as the primary initiator.

  • Policy updates and application
  • Manage downloads
  • System scans
  • Inventory reports

The client and server relationship relies heavily on BITS, Admin shares, RPC (at least for installation), WMI, AD, and WUA.

The client will regularly talk to the server, telling it about any changes it’s had since it’s last conversation, by way of xml.  It will also ask the server what it should be doing differently, to which the server sends the client it’s latest policy.  The client will review that policy then act, or do nothing depending on if there are any actionable changes.

Actionable changes could be installation of software, OS, OS configuration changes, even changes in the frequency of their conversations.  These exchanges of course are called policy updates, and I believe by default they are set to 90 minutes (no real reason to change it either).


Client Installation

There are multiple ways to install the SCCM client, and in a lot of ways, that method will vary depending on your environment.  I will stick to the basics and explain the process if done by server initiated push.  I will also discuss what is required.

First the server begins by initiating a PUSH, using local admin rights, it will copy down the CCMSETUP.EXE file to either c:\windows\ccmsetup or c:\windows\system32\ccmsetup

A service named CcmSetup is made and it begins transferring the client contents to the local machine and finalizing installation and cleanup of the directory.

A log of the transaction is left in the ccmsetup folder named ccmsetup.log

Once this process is complete, the client will perform it’s first policy update and make it’s active client existence known to it’s respective primary server.

 

So what if installation fails?

This isn’t a perfect world.  If you are pushing into an existing environment, things may have accidentally found there way out of standards and or flat broken.

Lets discuss what is required on a local PC for a successful install:

  • Resolvable hostname (proper DNS entry)
  • Service account with local admin rights
  • RPC access to OS components (such as registry)
  • Admin$ shares
  • WUA (Windows Update Agent)

Instead of explaining exactly why for each of these, lets explain how to resolve potential problems with each.  I also want to treat this as an all inclusive troubleshooting guide for the client, so I won’t limit things to just install failures.  Truthfully, if any of these breaks after installation, the client will most likely not function as intended.

Improper DNS entry:

From the local machine there is little you can do to resolve this problem.  Two methods that could resolve the problem are:

ipconfig /registerdns

This will attempt to update the DNS records for all adapters of the local machine.

ipconfig /flushdns

This will dump all resolver cache data on the local machine. (long shot, but I’ve seen this clear up client DNS conflicts from the push)

Any additional resolution would need to be done by the Domain Admin on the DNS server with the improper pointer references.

Service Account with local admin rights:

This is a very simple solution.  Add the appropriate service account to the local admins group on the client PC.  For Installation and operation, this account needs to be set for the client to perform it’s jobs.

RPC Access:

This one can have you scratching your head at times, but a majority of the times it’s tied to a firewall.  Make sure that local firewalls have exceptions built in for the SCCM server.  When in doubt, disable the firewall software to verify if it’s the culprit or not.

Also ensure that the RPC (RpcSs) and RPC Endpoint Mapper (RpcEptMapper) services are Started.

Some of these changes may require a restart before taking effect so  be aware of that while troubleshooting RPC denials.  It’s also worth mentioning there are a multitude of applications that could disrupt this functionality, so be sure to thoroughly investigate the machine for potential culprits.

Admin$ Shares:

First off, the service Workstation (LanManWorkstation) is responsible for these shares, as well as all SMB protocols on the local machine.  If it’s disabled, you will not have these shares.

One of the most direct methods for enabling admin shares is in:

HKLM\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters\AutoShareWks, 1

HKLM\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters\AutoShareServer, 1

Then restart the PC. 

Be aware this setting can be viewed as a security risk, and with that being said, some security software may actively disable them.  So treat your evaluation similarly to your RPC troubleshooting.

WUA Disabled:

The Windows Update service being disabled is a fairly simple solution provided there isn’t a GPO forcing it.  You can either enable and set the Windows Update service to Automatic (wuauserv).  Inside the control panel under Windows Update or Automatic updates set it to automatic.

WUA is responsible for system scans, patching, software delivery, essentially a vast majority of the clients functionality.  It is imperative that WUA is enabled.


Logs to Read, and Policy Updates

For the official list of log files, go here.

(http://technet.microsoft.com/en-us/library/bb693897.aspx)

 

I’m going to touch on the more immediate logs for troubleshooting the following issues.

  • Health
  • Policy
  • Connectivity
  • Licenses
  • Installs

Health:

CcmExec.Log, this log is one of the first stops for suspected bad installs.

ClientLocation.log, this log is a good place to verify that client has a healthy install with a site server.

StatusAgent.log, status messages for client components.  Also useful for connectivity issues.

Policy:

PolicyAgent.log, this holds policy request information, very helpful when pulling policy.

PolicyEvaluator.log, this log lets us know know if we are having issues applying policies.

Connectivity:

InternetProxy.log, if you are using unprotected DPs, this is the log to check.

Mpcontrol.log, logs record the state of the management point

LocationServices.log, attempted connectivity to MPs and DPs

Licenses:

Hman.log, if clients aren’t registering this is worth looking into.

Installs:

Ccmsetup.log, client installation happenings are recorded in this log.

Client.msi.log, output from the installer.


That concludes the overview of SCCM client installation and troubleshooting.  Happy problem solving.  For additional information on the client and troubleshooting check MSDN:

http://technet.microsoft.com/en-us/library/bb693982.aspx

and be sure to get involved with

http://www.myitforum.com/absolutenm/PPLSearch.aspx