Microsoft Identity Integration Server 2003 Developer Reference

Example: Searching for the Password Change History of a User

The password change history is stored in three WMI classes: MIIS_PasswordChangeHistorySource, MIIS_PasswordChangeHistoryTarget, and MIIS_PasswordChangeQueue.

The following Visual Basic Scripting Edition (VBScript) searches for the password change history for a user. You must be logged on as a member of the MIISAdmin or MIISBrowse security group in order to use the classes in this script.

Option Explicit

On Error resume next

Dim MIIS_AccountName
Dim MIIS_Password
Dim MIIS_MachineName
Dim Service
Dim objLocator 
Dim WMIQuery
Dim CsObjects
Dim CsObject
Dim CsObjCount
Dim SearchDomain
Dim SearchUser
Dim UserCsGuid
Dim Changes
Dim DetailCount
Dim PasswordChange
Dim BufferLen
Dim MAGuid
Dim MAName
Dim Targets
Dim Target
Dim TargetCount
Dim NumTargets
Dim QueueCount
Dim QueueEntry
Dim PasswordQueue
Dim NumQueue
Dim MVQuery
Dim ConnectorsCount
Dim RelatedCSObjects
Dim ConnectedCSObjects

Const MIIS_WMI_Namespace		= "root\MicrosoftIdentityIntegrationServer"
Const PktPrivacy				= 6
Const wbemAuthenticationLevelPkt= 6
Const strPad  = "								:"
Const strLine = "---------------------------------"
Const strQLine = " --------------------------------"
Const strTLine = "  -------------------------------"

MAGuid = array()
MAName = array()

BufferLen = Len(strPad)

' Check that you have the correct number of options.
If WScript.Arguments.Count <> 2 and WScript.Arguments.Count <> 5 Then
  If InStr(1,Wscript.Arguments.Item(0),"?",vbTextCompare) = 0 Then WScript.Echo _
	"Invalid arguments detected" & vbcrlf
  Usage
  WScript.Quit(1)
End If

SearchDomain = WScript.Arguments.Item(0)
SearchUser   = WScript.Arguments.Item(1)

If WScript.Arguments.Count = 5 Then
  MIIS_AccountName = WScript.Arguments.Item(2)
  MIIS_Password	= WScript.Arguments.Item(3)
  MIIS_MachineName = WScript.Arguments.Item(4)
End If

If Len(MIIS_AccountName) = 0 Then
  Set Service = GetObject("WinMgmts:{authenticationLevel=PktPrivacy}!" & MIIS_WMI_Namespace)
Else
  Set objLocator = CreateObject("WbemScripting.SWbemLocator")
  objLocator.Security_.AuthenticationLevel = wbemAuthenticationLevelPkt
  Set Service = objLocator.ConnectServer(MIIS_MachineName , MIIS_WMI_Namespace,  _
	MIIS_AccountName, MIIS_Password)
End If

If Err.Number <> 0 Then ErrorHandler("ERROR: " & Err.Description)

FindCSObject SearchDomain, SearchUser
CsObjCount = CsObjects.Count

If CsObjCount = 0 and Err.Number = 0 Then ErrorHandler(vbCrLf & _
  "Unable to locate " & SearchDomain & "\" & SearchUser & ".")
If CsObjCount = 0 and Err.Number <> 0 Then ErrorHandler(vbCrLf & _
  "ACTION: Verify that your user account is in the MIIS_Browse NT Security Group."_
   & vbCrLf & vbCrLf & "Error Number	 : " & Err.Number & vbCrLf & "Error Description: "_
   & Err.Description )

If IsNull(CSObject.MvGuid) Then 
  ErrorHandler(vbCrLf & "The connector space object is a disconnector.")
  Wscript.quit(0)
End If

UserCsGuid = CsObject.Guid
WMIQuery = "SELECT * FROM MIIS_PasswordChangeHistorySource WHERE " &_ 
  "CsGuid = '" & UserCsGuid & "'"
Set Changes = Service.ExecQuery (WMIQuery)

Wscript.Echo ""
WScript.Echo FormatOutput("Account") & CsObject.Account
WScript.Echo FormatOutput("Domain")  & CsObject.Domain
WScript.Echo FormatOutput("MA Name") & CsObject.MaName
WScript.Echo FormatOutput("MA Partition") & CsObject.PartitionName
WScript.Echo FormatOutput("MA Guid") & CsObject.MaGuid
WScript.Echo FormatOutput("CS Guid") & UserCsGuid
WScript.Echo FormatOutput("Password History Source Entries") & Changes.Count

MVQuery = "Select * from MIIS_CSObject where mvguid='" & CSObject.MVGUID & "'"

Set RelatedCSObjects = Service.ExecQuery(MVQuery)
WScript.Echo FormatOutput("Number of Connectors") & RelatedCSObjects.Count
ConnectorsCount = 0

Wscript.echo vbcrlf & strLine
Wscript.echo FormatOutput("WMI Password Change/Set History")
Wscript.echo strLine

For Each ConnectedCSObjects in RelatedCsObjects
  ConnectorsCount = ConnectorsCount + 1
  DisplayConnectorValues
Next
WScript.Echo ""

DetailCount = 0

For Each PasswordChange in Changes
  DetailCount = DetailCount +1
  QueueCount = 0
  TargetCount = 0

WScript.Echo vbcrlf & strLine
WScript.Echo FormatOutput(" Password History Source Entry " & DetailCount) 
WScript.Echo strLine & vbcrlf
  DisplayPwdSrcValues

WMIQuery = "Select * from MIIS_PasswordChangeQueue WHERE " &_
  "ReferenceGuid = '" & PasswordChange.ReferenceGuid & "'"
Set PasswordQueue = Service.ExecQuery (WMIQuery)

WMIQuery = "Select * from MIIS_PasswordChangeHistoryTarget WHERE " &_
  "ReferenceGuid = '" & PasswordChange.ReferenceGuid & "'"
Set Targets = Service.ExecQuery (WMIQuery)

PrintQueueTitle

NumQueue = PasswordQueue.count
NumTargets = Targets.count
WScript.Echo FormatOutput(" Password Target Entries") & NumTargets
WScript.Echo

For Each Target in Targets
  TargetCount=TargetCount+1
  DisplayPwdTargetValues 
Next

For Each QueueEntry in PasswordQueue
  QueueCount = QueueCount + 1
  Wscript.echo vbcrlf & strLine
  Wscript.echo FormatOutput(" Password Queue Entries")
  Wscript.echo strLine
  DisplayPwdQueueValues
Next

Next

Sub PrintQueueTitle
  WScript.Echo FormatOutput(" Password Queue Entries") & PasswordQueue.Count
End Sub

Sub FindCSObject(DomainName, UserName)
  On Error Resume Next

  WMIQuery = "SELECT * FROM MIIS_CSObject WHERE DOMAIN='" & DomainName & _
	"' and ACCOUNT='" & UserName & "'"

  Set CsObjects = Service.ExecQuery(WMIQuery)

  'Move to the first object in the CsObjects Collection and Exit
  For Each CsObject in CsObjects
	Exit For
  Next
End Sub

Sub DisplayPwdSrcValues
  WScript.Echo FormatOutput(" DN") & PasswordChange.DN
  WScript.Echo FormatOutput(" Source Server") & PasswordChange.SourceServer
  WScript.Echo FormatOutput(" Source Change Time") & PasswordChange.SourceChangeTime
  WScript.Echo FormatOutput(" MIIS Receive Time") & PasswordChange.MIISReceiveTime
  WScript.Echo FormatOutput(" Tracking Guid") & PasswordChange.GUID
  WScript.Echo FormatOutput(" Reference Guid") & PasswordChange.ReferenceGuid
  WScript.Echo FormatOutput(" MA Name") & GetMANameFromGuid(PasswordChange.MAGUID)
  WScript.Echo FormatOutput(" MA Guid") & PasswordChange.MAGUID
  WScript.Echo FormatOutput(" CS Guid") & PasswordChange.CsGUID
  'Wscript.echo vbCrLf & FormatOutput("Password History Source EventDetails")
  'Wscript.echo PasswordChange.EventDetails
End Sub

Sub DisplayPwdTargetValues
  Wscript.Echo strTLine
  WScript.Echo FormatOutput("  : Target Entry " & TargetCount & " of " & NumTargets)
  Wscript.Echo strTLine
  WScript.Echo FormatOutput("	DN") & Target.DN
  WScript.Echo FormatOutput("	Target Guid") & Target.Guid
  Wscript.Echo FormatOutput("	Reference Guid") & Target.ReferenceGuid
  WScript.Echo FormatOutput("	Retry Count") & Target.RetryCount
  WScript.Echo FormatOutput("	MA Name") & GetMANameFromGuid(Target.MAGUID)
  WScript.Echo FormatOutput("	MA Guid") & Target.MAGUID
  WScript.Echo FormatOutput("	CS Guid") & Target.CsGUID
  WScript.Echo FormatOutput("	RetryLimit") & Target.ReachedRetryLimit
  WScript.Echo FormatOutput("	MIIS Time Received") & Target.MIISReceiveTime
  Wscript.Echo FormatOutput("	Last Attempt Time") & Target.LastAttemptTime
  WScript.Echo FormatOutput("	Last Attempt Return Code") & Target.LastAttemptReturnCode '& vbCrLf
  'WScript.Echo FormatOutput("Attempt Details") & vbCrLf & Target.AttemptDetails
  'Wscript.echo FormatOutput("Password History Target EventDetails") & vbCrlf & Target.EventDetails
  WScript.Echo
End Sub

Sub DisplayPwdQueueValues
  If QueueCount > 1 Then Wscript.Echo strTLine
  WScript.Echo FormatOutput("  : Queue Entry " & QueueCount & " of " & NumQueue)
  Wscript.Echo strTLine
  WScript.Echo FormatOutput("	DN") & QueueEntry.DN
  WScript.Echo FormatOutput("	Queue Guid") & QueueEntry.Guid
  Wscript.Echo FormatOutput("	Reference Guid") & QueueEntry.ReferenceGuid
  WScript.Echo FormatOutput("	Retry Count") & QueueEntry.RetryCount
  WScript.Echo FormatOutput("	MA Name") & GetMANameFromGuid(QueueEntry.MAGUID)
  WScript.Echo FormatOutput("	MA Guid") & QueueEntry.MAGUID
  WScript.Echo FormatOutput("	CS Guid") & QueueEntry.CsGUID
  Wscript.Echo FormatOutput("	Last Attempt Time") & QueueEntry.LastAttemptTime
  WScript.Echo FormatOutput("	Last Attempt Return Code") & QueueEntry.LastAttemptReturnCode
  'WScript.Echo FormatOutput("Attempt Details") & vbCrLf & QueueEntry.AttemptDetails
  'WScript.Echo FormatOutput("Password Queue EventDetails") & vbCrLf & QueueEntry.EventDetails
  WScript.Echo
End Sub

Sub DisplayConnectorValues
  WScript.Echo FormatOutput("  Connector Object " & ConnectorsCount)
  Wscript.Echo strTLine
  If Len(ConnectedCsObjects.Account) > 0 Then
		WScript.Echo FormatOutput("  Account") & ConnectedCsObjects.Account
  Else
	WScript.Echo FormatOutput("  Account") & "N/A"
  End If
  If Len(ConnectedCsObjects.Domain) > 0 Then
	WScript.Echo FormatOutput("  Domain")  & ConnectedCsObjects.Domain
  Else  
	WScript.Echo FormatOutput("  Domain")  & "N/A"
  End If
  WScript.Echo FormatOutput("  MA Name") & ConnectedCsObjects.MaName
  WScript.Echo FormatOutput("  MA Partition") & ConnectedCsObjects.PartitionName
  WScript.Echo FormatOutput("  MA Guid") & ConnectedCsObjects.MaGuid
  WScript.Echo FormatOutput("  CS Guid") & ConnectedCsObjects.Guid
  If Len(ConnectedCsObjects.PasswordChangeHistory) > 0 Then 
	WScript.Echo FormatOutput("  PasswordChangeHistory") & vbCrLf & _
	ConnectedCSObjects.PasswordChangeHistory & vbcrlf
  Else
	WScript.Echo FormatOutput("  PasswordChangeHistory") & "None" & vbcrlf
  End If
  MADataAdd ConnectedCsObjects.MaName, ConnectedCsObjects.MAGuid
End Sub

Sub MADataAdd(CurrentMAName, CurrentMAGuid)
  Dim Size

  Size = Ubound(MAGuid) + 1
  ReDim Preserve MAName(Size)
  ReDim Preserve MAGuid(Size)
  MAName(Size) = CurrentMAName
  MAGuid(Size) = CurrentMAGuid
End Sub

Function GetMANameFromGuid(CurrentMAGuid)
  Dim i

  GetMANameFromGuid = "Unknown"

  For i = 0 To Ubound(MAGuid)
	If MAGuid(i) = CurrentMAGuid Then
	GetMANameFromGuid = MAName(i)
	Exit For		
	End If
  Next
End Function

Function FormatOutput(DisplayString)
  Dim DisplayStringLen

  DisplayStringLen = Len(DisplayString)

  If DisplayStringLen >= BufferLen Then
	FormatOutput = DisplayString & ": "
  Else
	FormatOutput = DisplayString & Right(strPad,  BufferLen - DisplayStringLen ) & " "
  End If
   
End Function

Sub ErrorHandler (ErrorMessage)
  WScript.Echo ErrorMessage
  WScript.Quit(1)
End Sub

Sub Usage
  Wscript.echo "Password Change History Source Usage Menu:" & vbCrlf
  Wscript.echo "cscript PasswordChangeHistorySource.vbs SearchDomain SearchUser"
  Wscript.echo "			 [MIIS_UserName MIIS_UserPassword MIIS_MachineName]" & vbcrlf
  Wscript.echo "SearchDomain		 Domain name to search for within the CS"
  Wscript.echo "SearchUser		 User name to search for within the CS"
  Wscript.echo "MIIS_UserName		Domain\UserName to connect as for a remote machine"
  Wscript.echo "MIIS_UserPassword	Password for the MIIS_UserName argument"
  Wscript.echo "MIIS_MachineName	 Name of the remote machine MIIS is running on" & vbcrlf
End Sub