Thursday, August 28, 2014

ASP - Cheap Debug Input Dumper

I call it: Dave's Dastardly Diabolical Debugging Dumbass Dumper, or just Debug Dump for short.  It simply prints out any form inputs and querystring inputs and then stops the page rendering process dead.  That allows you to structure a processing page to capture inputs and then dump them before proceeding to process them; allowing you a chance to see what may be going in the wrong direction before you go further into the debug abyss.

[asp]
<%
Sub Show_InputParams ()
   Dim fn, qv, fc, qc
    fc = 0
    qc = 0
    Response.Write "

Form Inputs

"

    For each fn in Request.Form()
        Response.Write "" & fn & " = " & Request.Form(fn) & "
"

        fc = fc + 1
    Next
    Response.Write "

QueryString Inputs

"

    For each qv in Request.QueryString()
        Response.Write "" & qv & " = " & Request.QueryString(qv) & "
"

        qc = qc + 1
    Next
    Response.Write "

(processing halted)

"

    Response.End
End Sub
%>
[asp]

To try this out the quickest way, paste that mess above into a new file and save it as "dumbass.asp".  Then access it via your browser along with some test parameters (querystring inputs for now).  something like "/mysite/dumbass.asp?test1=123&a=def&x=4321"

It should print out something like the following...

Form Inputs
(no form inputs found)

QueryString Inputs

test1 = 123
a = def
x = 4321
3 querystring inputs found

(processing halted)


ASP - Function to Get Windows Logon UserName

This requires that you have some form of authentication enabled on the web site configuration.  I prefer Windows Authentication, but forms or basic might also suffice.  Basically, regardless of the web browser, as long as some form of authentication is required, and the user provides it (or the browser hands it over silently, like IE usually does, cough-cough), it will spew forth the "logon_user" or "remote_user" server variable.  Using that, you can parse out a NetBIOS domain prefix, such as "contoso\dumbass" to return just the "dumbass" part.

[asp]
<%
Function Get_UserName()
    Dim tmp, result
    result = ""
    tmp = Trim(Request.ServerVariables("LOGON_USER"))
    If tmp = "" Then
        tmp = Trim(Request.ServerVariables("REMOTE_USER"))
    End If
    If tmp <> "" Then
        If InStr(tmp, "\") > 0 Then
            arrtmp = Split(tmp,"\")
            result = Lcase(arrtmp(1)
        Else
            result = Lcase(tmp)
        End If
    End If
    Get_UserName = result
End Function

' test it out...

If Get_UserName() = "dave" Then
    Response.Write "yay!  it's dave!"
Else
    Response.Write "boo.  it's not dave. bummer."
End If
%>
[/asp]

Wednesday, August 27, 2014

Function: Get Maintenance Window Status (VBScript, ASP and PowerShell flavors)

A little function you can use to determine if a date/time window is active, pending or expired.  I've provided both PowerShell, VBScript and ASP examples (almost the same thing).

Note that PowerShell requires defining the function before invoking it, with regards to single-file, sequential ("top-down") processing order.

[powershell]
function Get-TimeWindowStatus {
    Param(
        [parameter(Mandatory=$true)]$Start,
        [parameter(Mandatory=$true)]$End
    )
    $now = Get-Date
    $dif1 = $(New-TimeSpan -Start $Start -End $now).Minutes
    $dif2 = $(New-TimeSpan -Start $End -End $now).Minutes
    if ($dif1 -lt 0) {
        return -1
    }
    elseif ($dif2 -gt 0) {
        return 1
    }
    else {
        return 0
    }
}

$d1 = "8/27/2014 9:30:00"
$d2 = "8/27/2014 10:00:00"

switch (Get-TimeWindowStatus -Start $d1 -End $d2) {
    -1 {write-host "Maintenance window has not begun."}
    1  {write-hsot "Maintenance window has expired."}
    default {Write-Host "Maintenance window is active."}
}
[/powershell]

ASP and VBScript on the other hand pre-process script code, so you can define functions anywhere within a given script file, and the location for invoking the function doesn't matter as long as it's in the same file (or loaded in advance using "#include" if using ASP).

[asp]
d1 = "8/26/2014 16:00"
d2 = "8/27/2014 9:00"

Select Case TIME_WINDOW_STATUS (d1, d2)
    Case 0:  Response.Write "Maintenance window is in effect."
    Case 1:  Response.Write "Maintenance window has expired."
    Case -1: Response.Write "Maintenance window has not begun."
End Select

Function TIME_WINDOW_STATUS (startDT, endDT)
    Dim dd1, dd2, result
    dd1 = DateDiff("n", d1, NOW)
    dd2 = DateDiff("n", d2, NOW)
    If dd1 > 0 And dd2 < 0 Then 
        result = 0
    ElseIf dd1 < 0 Then
        result = -1
    ElseIf dd2 > 0 Then
        result = 1
    End If
    TIME_WINDOW_STATUS = result
    End Function
[/asp]

[vbscript]
d1 = "8/26/2014 16:00"
d2 = "8/27/2014 9:00"

Select Case TIME_WINDOW_STATUS (d1, d2)
    Case 0:  wscript.echo "Maintenance window is in effect."
    Case 1:  wscript.echo "Maintenance window has expired."
    Case -1: wscript.echo "Maintenance window has not begun."
End Select

Function TIME_WINDOW_STATUS (startDT, endDT)
    Dim dd1, dd2, result
    dd1 = DateDiff("n", d1, NOW)
    dd2 = DateDiff("n", d2, NOW)
    If dd1 > 0 And dd2 < 0 Then 
        result = True
    ElseIf dd1 < 0 Then
        result = False
    ElseIf dd2 > 0 Then
        result = False
    End If
    TIME_WINDOW_STATUS = result
End Function
[/vbscript]

Tuesday, August 26, 2014

SCCM Database Queries: Find Executable Files by Name, Version and Install Count

Find all instances of a particular file by its distinct Version number (e.g. "FileVersion" property).  In this example, I'm looking for what versions of Sysinternals' PsExec.exe are in the environment, and how many instances were found for each version.

[Begin T-SQL]
SELECT DISTINCT 
[ExecutableName0],[FileVersion0], COUNT(*) AS QTY
FROM [dbo].[v_GS_INSTALLED_EXECUTABLE]
WHERE ExecutableName0 = 'psexec.exe'
GROUP BY ExecutableName0, FileVersion0
ORDER BY FileVersion0
[End T-SQL]


Find Configuration Manager Collections with Both Direct and Query Rule Members

List all Collections which have both Direct members and Query-Rules assigned within your SCCM 2012 Site.  This also works with Configuration Manager 2007...

[begin T-SQL]
SELECT DISTINCT 
dbo.v_CollectionRuleDirect.CollectionID, 
dbo.v_Collection.Name
FROM 
dbo.v_CollectionRuleDirect INNER JOIN
dbo.v_CollectionRuleQuery ON dbo.v_CollectionRuleDirect.CollectionID = dbo.v_CollectionRuleQuery.CollectionID INNER JOIN
dbo.v_Collection ON dbo.v_CollectionRuleDirect.CollectionID = dbo.v_Collection.CollectionID
ORDER BY dbo.v_Collection.Name
[end T-SQL]

Tuesday, November 19, 2013

Deleting Sub-Folders with VBScript, Coffee and French Fries

Delete all sub-folders beneath a given root folder on multiple (remote) computers.  The old RD/RMDIR command will delete the named root folder along with sub-folders, by default.  This script leaves the root folder alone and only deletes the sub-folders.  Feel free to modify as needed.

'****************************************************************
' Filename..: fso_delete_subfolders.vbs
' Author....: David M. Stein
' Date......: 11/19/2013
' Purpose...: delete all sub-folders beneath a root path, on multiple computers
' NO WARRANTIES - USE AT YOUR OWN RISK - YOU DAREDEVIL YOU
'****************************************************************

Dim strServer, objSubFolder
Dim strFolderRoot, strSubFolder, x

Const strServerList = "SERVER1,SERVER2,SERVER3"
Const strRootPath = "D$\TEMP"

Set objFSO = CreateObject("Scripting.FileSystemObject")

For each strServer in Split(strServerList, ",")
wscript.echo "info: server is " & strServer
On Error Resume Next
strFolderRoot = "\\" & strServer & "\" & strRootPath
Set objFolder = objFSO.GetFolder(strFolderRoot)
If err.Number = 0 Then
For each objSubFolder in objFolder.SubFolders
strSubFolder = objSubFolder.Name
wscript.echo "info: deleting folder --> " & strFolderRoot & "\" & strSubFolder
x = objFSO.DeleteFolder(strFolderRoot & "\" & strSubFolder, True)
wscript.echo "info: result is " & x
Next
Else
wscript.echo "error [" & err.Number & "]: " & err.Description
wscript.echo "info: could be caused by folder-not-found."
End If
Next

Tuesday, July 31, 2012

File Search using WMI CIM_DataFile with VBScript

I looked around, but didn't find a script example that did exactly what I wanted, but I ran across several good alternatives. One thing I found was that if I don't specify the drive letter, it takes WAAAAAAAYYYYY longer to execute. Just a tip. In any case, I hope this helps someone out there...

'****************************************************************
' Filename..: fileSearch.vbs
' Author....: ScriptZilla / SkatterBrainz / Dave
' Date......: 07/30/2012
' Purpose...: search for files using WMI/CIM_DataFile
'****************************************************************
time1 = Timer

'----------------------------------------------------------------
' comment: search parameters
'----------------------------------------------------------------

strFileExt  = "syn"
strFileName = "*"
strDriveLtr = "c:"
strComputer = "."

'----------------------------------------------------------------
' function: 
'----------------------------------------------------------------

Function StringDate(dv)
 Dim xdy, xdm, xdd, xdh, xdn, tmp
 ' example: 20120729195837.171181-240
 xdy = Mid(dv,1,4) ' year
 xdm = Mid(dv,5,2) ' month
 xdd = Mid(dv,7,2) ' day
 xdh = Mid(dv,9,2) ' hour
 xdn = Mid(dv,11,2) ' minute
 tmp = xdm & "/" & xdd & "/" & xdy & " " & xdh & ":" & xdn
 StringDate = FormatDateTime(tmp, vbShortDate) & " " & _
  FormatDateTime(tmp, vbLongTime)
End Function

'----------------------------------------------------------------
' comment: main script code begins
'----------------------------------------------------------------

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

If strFileName = "*" Then
 query = "Select * from CIM_DataFile Where Drive='" & strDriveLtr & "'" & _
  " AND Extension='" & strFileExt & "'"
Else
 query = "Select * from CIM_DataFile Where Drive='" & strDriveLtr & "'" & _
  " AND FileName = '" & strFileName & "'" & _
  " AND Extension='" & strFileExt & "'"
End If

wscript.echo "info: search criteria = " & strFileName & "." & strFileExt & " on " & strDriveLtr
Set colFiles = objWMIService.ExecQuery(query)

wscript.echo "info: beginning search..."

counter = 0
For Each objFile in colFiles
 counter = counter + 1
    wscript.echo objFile.Drive & objFile.Path & _
     objFile.FileName & "." & objFile.Extension & _
     vbTab & StringDate(objFile.CreationDate) & _
     vbTab & StringDate(objFile.LastModified) & _
     vbTab & objFile.FileSize
Next

wscript.echo "info: " & counter & " matching files found"
wscript.echo "info: " & Timer - time1 & " seconds"