Just earned my Microsoft Certified IT Professional: Enterprise Administrator (MCPIT:EA).
Hopefully that, with my Red Hat Certified Engineer (RHCE), makes me an attractive hire (not that I am looking right now)
Author Archive | jbmurphy
Waking up a SCCM collection from vbscript.
I wanted to wake up all the machines in a collection using a vbscript. I know that SCCM has this built in, but I could not get it working. To troubleshoot I figured I would write a script to get collection members, and then wake them via the command line with this tool: http://www.gammadyne.com/cmdline.htm#wol
GetCollectionMembers "XXX00018" Sub GetCollectionMembers (COLLECTION_NAME) Set objLocation = CreateObject("WbemScripting.SWbemLocator") Set objService = objLocation.ConnectServer("SERVERNAME", "root\SMS\site_XXX") strQuery = "SELECT * FROM SMS_FullCollectionMembership WHERE CollectionID = '" & COLLECTION_NAME & "'" Set objSourceCollectionMembers = objService.ExecQuery(strQuery) For Each Resource In objSourceCollectionMembers WakeMachine objService,Resource.ResourceID Next End Sub Sub WakeMachine (objService,ResourceID) Set Machines = objService.ExecQuery("Select * From SMS_R_System where ResourceID =" & ResourceID) For Each Machine In Machines Set objShell = CreateObject("Wscript.Shell") strCurrentDir = Replace(WScript.ScriptFullName,WScript.ScriptName,"") strCommand = strCurrentDir & "\wol.exe " & Replace(Machine.MACAddresses(0),":","") Set objExecObject = objShell.Exec(strCommand) Next End Sub
SCCM “trickle” install.
We wanted to deploy software to our environment via and assigned advertisement in SCCM, but we wanted to be able to install packages to a subset of a collection. If there is an issue the next day, the whole enterprise would not down. We already had a collection that identified machines that need the package, we just want to deploy to the first 15 one day, and another 15 the next day.
Since WQL does not allow a SQL “TOP” I did not think I would be able to do it via a complex query. So I wrote the following vbscript to find machines in one Collection and add them to another collection:
Sub CopyMachinesToCollection (SOURCE_COLLECTION,TARGET_COLLECTION,ResourcesAtATime) Set objLocation = CreateObject("WbemScripting.SWbemLocator") Set oService = objLocation.ConnectServer("server", "root\SMS\site_XXX") Set oSourceCollectionMembers = oService.ExecQuery("SELECT ResourceID, Name FROM SMS_FullCollectionMembership WHERE CollectionID = '" & SOURCE_COLLECTION & "'") Set oTargetCollection = oService.Get("SMS_Collection.CollectionID='" & TARGET_COLLECTION & "'") ' Add ResourcesAtATime resources to counter=0 For Each Resource In oSourceCollectionMembers if counter < ResourcesAtATime then 'Wscript.Echo Resource.ResourceID & "-" & Resource.Name Set DirectRule = oService.Get("SMS_CollectionRuleDirect").SpawnInstance_() DirectRule.ResourceClassName = "SMS_R_System" DirectRule.ResourceID = Resource.ResourceID DirectRule.RuleName = Resource.Name oTargetCollection.AddMembershipRule DirectRule, SMSContext oTargetCollection.RequestRefresh False end if counter=counter+1 Next End Sub Sub DeleteTargetCollection (TARGET_COLLECTION) Set objLocation = CreateObject("WbemScripting.SWbemLocator") Set oService = objLocation.ConnectServer("svnyem01", "root\SMS\site_SVC") Set oTargetCollection = oService.Get("SMS_Collection.CollectionID='" & TARGET_COLLECTION & "'") ' Delete all in oTargetCollection If Not IsNull(oTargetCollection.CollectionRules) Then For Each Rule In oTargetCollection.CollectionRules wscript.echo Rule.RuleName oTargetCollection.DeleteMembershipRule Rule Next oTargetCollection.RequestRefresh False End If End Sub
Second sub removes all machines from the collection, and the first copies the first “x” from the soure to the destination
iPad app pricing?
Just was reading this article. I couldn’t agree more with this statement. It costs equal or more to but the WSJ on the iPad?
Compare the strategies and thinking. On the one hand we have a set of pricing models that deliver marginal value for premium prices and show very little that differentiate themselves from the web experience, although they expect to charge more. These pricing models are based on a sense of entitlement to set pricing as it was in the days of print. I won’t even call them strategies because they lack any kind of realistic strategic thinking
Laying on the couch blogging from my iPad
Sweet!!!
Google Chrome for the Mac – Pin tab is back
5.0.366.0 dev seems to have added pin tab back in. Let’s hope it stays. Thanks Mr. Google.
Powershell signing, makecert.exe and group policy – Part 2
In the previous post I showed how to create self signed signing certs via the makecert tool. Once I made the pfx files, and signed my script, I need to make the server I was working see the certificate chain. I created a GPO and applied it to the server OU. I added the Root cert to Trusted Root Certification Authorities, and I added the Cert to Trusted Publishers Certificates. Now when I open a signed script on a server, I no longer have to change the Set-ExecutionPolicy RemoteSigned and add the network path to the Local Intranet zone.
Powershell signing, makecert.exe and group policy – Part 1
We don’t have a pki infrastructure at my current job, and I like to keep my powershell scripts on my network drive. So I needed a way to run my .ps1 files off a network drive. Setting Set-ExecutionPolciy to Unrestricted seemed like a bad idea. So I looked into using a signed script and setting Set-ExecutionPolicy to RemoteSigned. I could not justify $300 to buy a trused third party cert, so I looked at makecert.exe from the Windows SDK.
First step make the Root CA cert, private key, and pxf.
- makecert -n “CN=RootName” -a sha1 -eku 1.3.6.1.5.5.7.3.3 -r -sv Root.pvk Root.cer
- pvk2pfx.exe -pvk Root.pvk -spc Root.cer -pfx Root.pfx -pi password
makecert and pvk2pfx can be found in the Windows SDK or in the Visual Studio bin directory. First command results in a private key (.pvk) and a certificate (.cer). Second command makes a pfx out of the first 2.
Second step is to create a certificate from the root cert above.
- makecert -pe -n “CN=Certificate” -a sha1 -eku 1.3.6.1.5.5.7.3.3 -ic Root.cer -iv Root.pvk -sv Certificate.pvk Certificate.cer
- pvk2pfx.exe -pvk Certificate.pvk -spc Certificate.cer -pfx Certificate.pfx -pi password
Now we are ready to sign our powershell script.
- $cert = Get-PfxCertificate Certificate.pfx
- Set-AuthenticodeSignature -Filepath script.ps1 -Cert $cert
Probably can be combined into one line, but I am not a guru yet.
Next post will talk about how I added this certs above to all the servers.
New MD5 based backup script
I found this use of md5 and find the other day. I based my current backup script around it. The md5 will show if anyone modifies a file, or adds/removes a file in the web hosting root (/var/www) or in the config directory (/etc/httpd/conf.d/). If there is a change then zip each site up individually and move to a backup folder to be rsynced to other servers.
NewWWWMD5=$(find /var/www/ -type f -exec md5sum {} \; | md5sum - | awk '{print $1}') OldWWWMD5=$(cat $PARENTDIR/_var_www_*.md5) NewConfMD5=$(find /etc/httpd/conf.d/ -type f -exec md5sum {} \; | md5sum - | awk '{print $1}') OldConfMD5=$(cat $PARENTDIR/_etc_httpd_conf.d_*.md5) if [ $NewWWWMD5 = $OldWWWMD5 -a $NewConfMD5 = $OldConfMD5 ]; then echo "Neither /var/www/ nor /etc/httpd/conf.d/ have changed" else rm -rf $BACKUPDIR/*Files echo "/var/www or /etc/httpd/conf.d has changed" mkdir -p $BACKUPDIR-Files # backup /var/www for directory in /var/www/*; do if [ -d $directory ]; then bu $directory; fi done # replace previous /var/www MD5 rm -f $PARENTDIR/_var_www_*.md5 find /var/www/ -type f -exec md5sum {} \; | md5sum - | awk '{print $1}' > $PARENTDIR/_var_www_$CURRENTDAY.md5 #backup /etc/httpd/conf.d bu "/etc/httpd/conf.d" # replace previous /etc/httpd/conf.d MD5 rm -f $PARENTDIR/_etc_httpd_conf.d_*.md5 find /etc/httpd/conf.d/ -type f -exec md5sum {} \; | md5sum - | awk '{print $1}' > $PARENTDIR/_etc_httpd_conf.d_$CURRENTDAY.md5 fi
Seems to work!
PowerShell is great
Okay, I drank the Kool-Aid. PowerShell is awesome. The first thing I wanted to do was make sure my $profile is always the most current no matter what machine was on. In the past I had a batch file that I would run that would open my command prompt the way I wanted. I modified that so if PowerShell is installed, then get my profile up-to-date and then launch PowerShell. This is part of my current batch file:
IF NOT EXIST "c:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" GOTO NO_PS powershell -NoProfile $a=(Split-Path $profile -parent);if (!(Test-Path $a)) {New-Item $a -type directory}; powershell -NoProfile if (!(Test-Path $profile)) {Copy-Item %~dp0Scripts\Microsoft.PowerShell_profile.ps1 (Split-Path $profile -parent)} powershell -NoProfile if (!(Compare-Object $(Get-Content $profile) $(Get-Content Scripts\Microsoft.PowerShell_profile.ps1)).Count -eq 0 ) {Copy-Item Scripts\Microsoft.PowerShell_profile.ps1 (Split-Path $profile -parent)} @start %COMSPEC% /K PowerShell -nologo
This will copy over my profile if it does not exist or is a different version. Now when I am on a server with PowerShell I can double click my batch file and my environment is up to date!