Several months ago I posted a server inventory report. During a recent true-up, we discovered that some of the servers were reporting twice the number of processors!!! Not a good thing with SQL servers. The issue is turns out is Hyper Threading. If it’s enabled you’ll see twice the number of CPUs. The current quick fix is to add a column indicating if Hyper Threading is enabled.

If your HW Inventory, under Processor, simply check “Is Hyperthread Enabled”. When inventories start coming in, they will report back a 1 (enabled) or 0 (disabled or N/A) in the PROCESSOR_DATA table and v_GS_Processor view.

For reporting, I used:
ISNULL(v_GS_Processor.IsHyperThreadEnabled0, 39909) AS ‘Hyper Threaded’

This way, if an inventory hasn’t come in on a device it 1) won’t error out the report, and 2) reports 39909 which is my l33t type for “ERROR”. It’s a good way to get the server folks to tell me when their SCCM Clients are broken…

So we had an admin leave awhile back and soon afterwards some stuff stopped working. I won’t get into the details, but the root cause was not malicious. He’d been here for awhile and automated some tasks using task scheduler, that were set to run using his administrative account. While I applaud the effort to set stuff like this up, it wasn’t documented and it put us in a bind for a little bit. So if you’re thinking about doing something like this, first let someone know and second use a domain account with specific rights tailored to the task. Your coworkers thank you.

Anyway, after all the dust settled I was tasked to check all our systems for scheduled tasks running with accounts from our admin domain. At first I thought this was easy, SCCM captures everything about everything right? Well it doesn’t collect data about scheduled tasks, which seems odd to me because they can be used for some pretty malicious stuff. I ended up with the following as a bandaid scanner to check for the specific scenario of checking systems for a scheduled task running as a user in a specific domain. It’s quick and dirty like most of my scripts, but it got the job done once.

In the future, I’d like to tweak it a little to run on a local machine, just flag pass/fail, and set that up in DCM so that I can run a report once every month or so. I’m also thinking about ‘whitelisting’ tasks so that if a machine fails the whitelist check we’d get an alert through SCCM to go look at the box and see what unexpected task is running on the machine. So without futhre adieu:

If you’re planning on using this, there are a few things you need to change and/or review for your environment. So make sure you read and understand the code before you blindly drop it on your machine and run it.

#####################################################################
# Find Admin Tasks
#
# AUTHOR: David Bennett
#
# Purpose: Locate scheduled tasks from a list of remote systems
# which run under a admin account context
#
# USE: Place in a folder with FindAdmin.txt
# Populate FindAdmin.txt with a list of machines to be checked
# –One machine name per line…
# Ensure get-executionpolicy will allow PowerShell scripts
# Open a PS Console or CMD prompt, CD to containing folder
# Execute .\FindAdminTasks.ps1
#
#####################################################################

CLS

Remove-Item .\tasks.txt
$ErrorActionPreference = “silentlycontinue”

$InputList = get-content .\FindAdmin.txt
$InputCount = $InputList.Count
$runtime = $InputList.Length * 3 / 60
“Expected runtime for $InputCount systems is $runtime minutes”

# For Each Computer, get results to tasks.csv
foreach ($Computer in $InputList)
{
If(Test-Connection -ComputerName $Computer -Quiet -Count 2)
{
“Checking $Computer”
#Set up native command
$ScriptBlock =
$CMD = ‘schtasks.exe’
$arg1 = “/query”
$arg2 = “/S”
$Arg3 = “$Computer”
$arg4 = ‘/V’
$arg5 = ‘/FO’
$arg6 = ‘TABLE’
$arg7 = ‘/NH’
&$cmd $arg1 $arg2 $Arg3 $arg4 $arg5 $arg6 >> .\tasks.txt
}
Else {“Connection to $Computer failed”}
}

$tasks = Get-Content .\tasks.txt

“Line Title System User Status Next Run Time”
Foreach ($line in $tasks)
{
#Filter out bad rows
#Remove Folder Info
If($line.Length -ge 80) {
#Remove Divider Lines
If (!$line.StartsWith(“=”)) {
If (!$line.StartsWith(“Host”)) {

#Build Output Fields
$LineNumber = $line.ReadCount
If ($LineNumber -le 9) {$LineNumber = “$LineNumber “}
If ($LineNumber -le 99 -and $LineNumber -ge 10) {$LineNumber = “$LineNumber “}
If ($LineNumber -le 999 -and $LineNumber -ge 100) {$LineNumber = “$LineNumber “}
$RunAs = $line.Substring(460,15)
$ComputerName = $line.Substring(0,15)
$TaskName = $line.Substring(15,40)
$Status = $line.Substring(81,15)
$NRT = $line.Substring(58,13)

#Remove Blank Rows
If (!$ComputerName.StartsWith(” “)) {
#Finally, output only systems with a Admin account as RunAs
If ($RunAs.StartsWith(“\”))
{
“$LineNumber $TaskName $ComputerName $RunAs $Status $NRT”
}
}
}
}
}

}

Change of Pace

Posted: June 18, 2014 in Uncategorized

I know I haven’t written anything here for awhile. Mostly because I was trying to keep this blog mostly technical and most of my technical stuff right now is hush-hush. However, my other passions are IT Service Management and Information Security issues.

I spent a couple years as the Change Manager for a large organization. I’m still not sure how I wound up in the position as my prior experience in IT Service Management was pretty much nill, but it was one of the greatest learning experiences of my life. I think that I truely did enjoy what I was doing even if I didn’t have the experience to accomplish a lot of the goals I had… Since then, I have got my ITIL Foundations and Microsoft MOF certs. I’m currently in an engineering position so I don’t use them much but they might come in handy down the road. So expect some new posts along those lines and I try to stay current in the field.

Oddly, from that job I learned not to bite off more than I can chew, which led me to recently turn down a VP position in a startup a couple weeks ago. It sounded great, but I just don’t have the business skill to work at that level yet. And that in turn does have my looking casually into managerial positions. I’m not going to leave my current employer anytime soon because they’re paying for my school right now though…

Secondly, Information Security. I’ve always been interested in the field. When I was active duty Air Force several years back, they required all managerial type positions to get their CISSP certification. Probably the best thing the AF did for me. I’m also currently enrolled in a BS program for Cyber Security. After 20-something years of information security interest, I’m really just formalizing what I already know but I’m finally doing it. I still spend 3-4 hours a week reading up on the latest security trends. So again, I’ll probably do a couple write-ups on here for practice in that field as well.

So I had a need to script an install in which a pre-requisite was to enable a windows feature. It took me awhile to work it out so I figured I’d write up a post since I haven’t put much up here recently.


'--------------------------------------------------
' Windows Features Installer
'
'AUTH: David Bennett
'USE: cscript DISM.vbs feature_name
'Desc: Takes on parameter, the feature name. Will
' evaluate the system to see if the feature is
' already installed and will only install if
' it's neeed.
'Out: None
'--------------------------------------------------

'------------------Setup
Option Explicit
'On Error Resume Next
DIM strInput
DIM wshShell : Set wshShell = CreateObject("WScript.shell")

If WScript.Arguments.Count = 0 Then
Wscript.echo "Useage: cscript DISM.vbs "
Wscript.quit
End If
strInput = Wscript.Arguments(0)

'------------------Main Script
If checkDISM(strInput) = FALSE Then EnableDISM(strInput)

'------------------Functions
Function checkDISM(feature)
DIM DISMTest, strResult
set DISMTest = wshShell.exec("DISM /online /get-featureinfo:" & feature)
do until DISMTest.status = 1 : wscript.sleep 10 : loop
strResult = DISMTest.stdout.Readall
If Instr(strResult, "Enabled") Then
checkDISM = TRUE
wscript.echo feature & " is installed"
Else
checkDISM = FALSE
wscript.echo feature & " is not installed"
End If
End Function

Sub EnableDISM(feature)
DIM DISMInstall, strResult
SET DISMInstall = wshShell.exec("DISM /online /enable-feature /featurename:" &_
feature)
do until DISMInstall.status = 1 : wscript.sleep 10 : loop
strResult = DISMInstall.stdout.readall
wscript.echo feature & " installed"
wscript.echo strResult
End Sub

Migrate DHCP from OldServer, server 2003, to NewServer, server 2008

Pre-checks

1) Ensure you have a test/validation system. I just set my workstation to a reserved IP on OldServer before I do step 2 unless I’m working on a different site.
a. Execute IPConfig /renew and make sure you don’t get any errors.
2) Ensure OldServer DHCP is backed up
3) Ensure there are no other services running on OldServer
NOTE: I had KMS running on one and I almost took that down for the enterprise…
a. If there are any other services on OldServer
i. Plan a migration path for that service, or leave it in place.
ii. If it’s staying in place will re-IP’ing OldServer impact that service?
4) Make sure you have an IP to move OldServer to. Same subnet would be best.

Migration

1) On NewServer install the Windows Server Migration Tools (SMT)
a. In Server Manager start the Add Features Wizard
b. Check Windows SMT, click next, confirm, etc.
2) Create a Server 2003 Deployment Package
a. On NewServer open an elevated command prompt
b. CD to %systemroot%\system32\ServerMigrationTools
c. To create the deployment package, execute:
SmigDeploy.exe /package /architecture x86 /os ws03 /path c:\SMIG
NOTE: Change the OS / Architecture settings as needed. But above will work for an x86 Server 2003 machine.
It will put all files in c:\SMIG\SMT_ws03_x86
d. Copy the SMT_ws03_x86 folder to the root of OldServer
e. On OldServer, open an elevated command prompt
f. CD to c:\ SMT_ws03_x86 and to install SMT execute:
SmigDeploy.exe
NOTE: This will install SMT on OldServer and give you a nifty PowerShell prompt, we’ll use it later.
The package is needed because Server 03 doesn’t have a SMT feature to install.
g. On OldServer, stop the DHCP service
h. In the PowerShell prompt on OldServer, to export DHCP settings execute:
Export-SmigServerSetting –FeatureID DHCP
i. Enter a path to save the exported settings
j. Enter a password (6 characters min). Remember it, you’ll need it for the import
k. It’ll run for a while. When done, copy the folder that you exported to over to NewServer so that you can import it later
l. You can now unauthorized OldServer from the domain
i. In the DHCP Console, right click the server and select Unauthorize
ii. You do need special permissions to do this. Domain Admin by default can do it
m. Re-IP OldServer to an open IP (note the old IP, gateway, mask, etc. if they aren’t in your CMDB)
n. Re-IP NewServer to OldServer’s original settings
NOTE: the reason for the re-ip’ing is that data flow is usually something like this:
i. Client broadcasts looking for an IP
ii. The default gateway has an IP Helper setting, that directs the broadcast to the DHCP server (by IP)
iii. The DHCP server replies to the default gateway, which passes it back to the client.
So essentially DHCP traffic is dependent on static IP’s. In fact I don’t think the DHCP service will
even run if the system is set up for a dynamic IP
o. On NewServer, click Start –> Admin Tools –> Windows Server Migration Tools (folder) –>
RIGHT CLICK Windows Server Migration Tools (program) –> Run as Administrator.
This will open a PowerShell prompt.
p. In the PowerShell prompt, to import the DHCP settings from OldServer execute:
Import-SmigServerSetting –FeatureID DHCP –Verbose
q. When prompted, give it the path that you copied the export folder from OldServer to
r. When prompted, give it the password that you encrypted the export folder with
s. It’ll run upwards of 5-10 minutes, don’t get impatient
t. When done, set the DHCP service to Automatic and Started on NewServer
u. Open the DHCP console on NewServer and verify the scopes look right.
v. Authorize DHCP on the domain for NewServer

Post Checks.

1) Verify IP addresses on OldServer and NewServer are correct
2) Verify all A and Pointer records are updated in DNS correctly
3) Verify that the DHCP service is disabled/stopped on OldServer
4) Verify that the DHCP service is automatic/started on NewServer
5) On the same test system from Pre Checks, execute IPConfig /renew
a. Verify no errors
6) Test any additional services that may still exist on OldServer
7) If no remaining services exist on OldServer consider decommissioning the machine