How to: Set Passwords
This topic contains code examples to set passwords on connected data sources using the Windows Management Instrumentation (WMI) Provider.
Note
For clarity, the passwords are exposed in the example. We recommend that you modify the examples so that the passwords are encrypted and not exposed.
The following Visual Basic Scripting Edition (VBScript) example changes the password on an ADAM, Sun, or Netscape data source using the WMI provider. The example has the following functions:
The main function that sets the password on a connector space object.
The GetMATypeFromCSObject function gets the name of the management agent that is used to create the connector space object. The management agent performs the password operation on the object in the connected data source.
The FindCSObject function searches the connector space for the object with the password that is going to be set.
The ErrorHandler function handles any errors that occur in the script. This function contains minimal error handling. Expand this function for your purposes.
If you saved this script to a file called Setpassword.vbs, the following is the syntax for the script: setpassword.vbs SearchDomain SearchUser NewPassword
.
The script requires the following arguments if this script is run from the FIM Synchronization Service server using the account that is a member of the MIISPasswordSet security group:
SearchDomainthe domain of the account with the password to set.
SearchUserthe user name of the account with the password to set.
NewPasswordthe new password.
An example of this script would be: setpassword.vbs fabrikam, jeffsmith, NewPassword
If the script is run remotely, you must also supply the following arguments: setpassword.vbs SearchDomain SearchUser NewPassword MIIS_AccountName MIIS_Password MIIS_MachineName
MIIS_AccountName the name of the account that is a member of the MIISPasswordSet security group.
MIIS_Password the password of the account that is a member of the MIISPasswordSet security group.
MIIS_MachineName the name of the FIM Synchronization Service server.
An example of this script would be: setpassword.vbs fabrikam, jeffsmith, NewPassword, loripenor, MIISAdminPassword, MIISServer
Option Explicit
On Error resume next
Dim MIIS_AccountName
Dim MIIS_Password
Dim MIIS_MachineName
Dim SearchDomain
Dim SearchUser
Dim NewPassword
Dim Service
Dim objLocator
Dim WMIQuery
Dim CsObjects
Dim CSObject
Dim CSObjectMVGUID
Dim RelatedCSObjects
Dim RelatedCSObject
Dim MVQuery
Dim LenMV
Dim MAQuery
Dim MAObjects
Dim MAObject
Dim Status
Const MIIS_WMI_Namespace = "root\MicrosoftIdentityIntegrationServer"
Const PktPrivacy = 6
Const wbemAuthenticationLevelPkt= 6
Const impersonate = 3
' Check for the correct number of options
If WScript.Arguments.Count <> 3 and WScript.Arguments.Count <> 6 Then
WScript.Echo "Missing Arguments"
WScript.Quit(1)
End If
' Load the arguments into variables
SearchDomain = WScript.Arguments.Item(0)
SearchUser = WScript.Arguments.Item(1)
NewPassword = WScript.Arguments.Item(2)
If WScript.Arguments.Count = 6 then
MIIS_AccountName = WScript.Arguments.Item(3)
MIIS_Password = WScript.Arguments.Item(4)
MIIS_MachineName = WScript.Arguments.Item(5)
End If
' Get service, based on account information
If MIIS_AccountName = "" then
Set Service = GetObject("WinMgmts:{impersonationLevel=impersonate,authenticationLevel=PktPrivacy}!" & MIIS_WMI_Namespace)
Else
Set objLocator = CreateObject("WbemScripting.SWbemLocator")
objLocator.Security_.ImpersonationLevel = impersonate
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)
' Find the CS Objects for the specified SearchDomain and SearchUser
FindCSObject
If CsObjects.Count = 0 Then
ErrorHandler("Unable to locate " & SearchDomain & "\" & SearchUser & ".")
End If
If IsNull(CSObject.MvGuid) Then
ErrorHandler("The connector space object is a disconnector. The password was not set.")
End If
Wscript.Echo ""
Wscript.Echo "Located CS Object for " & SearchDomain & "\" & SearchUser & "."
Wscript.Echo "Locating related connectors..."
' Find the connectors for the MV Object
MVQuery = "Select * from MIIS_CSObject where mvguid='" & CSObject.MVGUID & "'"
Set RelatedCSObjects = Service.ExecQuery(MVQuery)
If RelatedCSObjects.Count = 0 Then
ErrorHandler("No related CS objects found for " & SearchDomain & "\" & SearchUser & ".")
End If
Wscript.Echo "Located " & RelatedCSObjects.Count & " connectors for MV Object."
Wscript.Echo "Locating MA(s) for connected CS object(s)..."
Wscript.Echo ""
' Get the MA objects and update the password
For Each RelatedCSObject in RelatedCSObjects
If (LCase(RelatedCSObject.ObjectType) <> "inetorgperson") and (LCase(RelatedCSObject.ObjectType) <> "user") then
Wscript.Echo "Wrong object type detected, Skipping " & RelatedCSObject.MaName & "'s CS object: " & LCase(RelatedCSObject.ObjectType)
Wscript.Echo "DN : " & RelatedCSObject.Dn
Else
' get the MA Objects for the specified SearchDomain and SearchUser
GetMATypeFromCSObject
If IsNull(MAObject) Then
Wscript.Echo "Unable to retrieve the MA " & RelatedCSObject.MaName & "'s for CS Object:"
Wscript.Echo "DN : " & RelatedCSObject.Dn
Wscript.Echo "MA Type: Unknown"
Else
If MAObject.Type <> "Active Directory Application Mode (ADAM)" and MAObject.Type <> "Sun and Netscape directory servers" Then
Wscript.Echo "Wrong MA type detected, Skipping " & RelatedCSObject.MaName & "'s CS Object:"
Wscript.Echo "DN : " & RelatedCSObject.Dn
Wscript.Echo "MA Type: " & MAObject.Type
Else
Wscript.Echo "Updating password for " & RelatedCSObject.MaName & "'s CS Object:"
Wscript.Echo "DN : " & RelatedCSObject.Dn
Wscript.Echo "MA Type: " & MAObject.Type
Status = RelatedCSObject.SetPassword(newPassword)
If Status = "success" then
Wscript.Echo "Result : Successful."
Else
Wscript.Echo "Result : Failed."
Wscript.Echo "Status : " & Status
End If
End If
End If
End If
Wscript.Echo ""
Next
' Get the MA Objects for the specified SearchDomain and SearchUser
Function GetMATypeFromCSObject()
MAQuery = "Select * from MIIS_ManagementAgent where guid='" + RelatedCSObject.MaGuid + "'"
Set MAObjects = Service.ExecQuery(MAQuery)
'Move to the first object in the MAObjects Collection and Exit
For Each MAObject in MAObjects
Exit for
Next
End Function
' Find the CS Objects for the specified SearchDomain and SearchUser
Function FindCSObject()
WMIQuery = "Select * from MIIS_CSObject where " + _
"(Domain='" + searchDomain + "' and Account='" + searchUser + "') or " + _
"(FullyQualifiedDomain='" + searchDomain + "' and Account='" + searchUser + "') or " + _
"(Domain='" + searchDomain + "' and UserPrincipalName='" + searchUser + "') or " + _
"(FullyQualifiedDomain='" + searchDomain + "' and UserPrincipalName='" + searchUser + "')"
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 Function
Sub ErrorHandler (ErrorMessage)
WScript.Echo ErrorMessage
WScript.Quit(1)
End Sub
The following C# example changes the password on an ADAM, Sun, or Netscape data source using System.Management namespace to invoke the WMI provider. The example has to be run by an account that is a member of the MIISPasswordSet security group.
The example has the following functions:
The main function is the start of the program. This function passes the domain name, the user name, and the new password of the accountwhich has the password to be setto the next function.
The SetNewPassword function sets the password of the account specified in the previous function.
The FindCSObject function searches the connector space for the object with the password to set. If the connector space exists, the function returns a ManagementObject object.
The GetMATypeFromCSObject function returns the type of management agent used to create the object with the password to set. Some connected data sources allow setting passwords on objects. The function is used to set passwords on objects from data sources that allow setting passwords.
The GetManagementObjectCount function explicitly enumerates the ManagmentObjectCollection object after the count property is read.
using System;
using System.Management;
namespace MIISSamples
{
public class SetPasswordExample
{
// These constants assume that this application is on the same server
// as <tla rid="fim_sync_short"/>. If this program is run from a separate computer, change
// the following constants.
const string MIIS_AccountName = null; // MIISPasswordSet Group member
const string MIIS_Password = null; // Password for above member
const string MIIS_MachineName = null; // <tla rid="fim_sync_short"/> Server name
// WMI namespace path for the <tla rid="fim_sync_short"/> server.
const string MIIS_WMI_Namespace = @"root\MicrosoftIdentityIntegrationServer";
static void Main(
string searchDomain,
string searchUser,
string newPassword
)
{
ManagementScope WMInamespace;
// Create the WMI management scope object to connect to the
// <tla rid="fim_sync_short"/> server. If the password for the MIISPasswordSet group
// member is null, then <tla rid="fim_sync_short"/> is installed on the local computer.
// Enable the PacketPrivacy Connection Option to ensure that all
// communication is encrypted.
if ( MIIS_Password != null )
{
ConnectionOptions connOpt = new ConnectionOptions();
connOpt.Username = MIIS_AccountName;
connOpt.Password = MIIS_Password;
connOpt.Authentication = AuthenticationLevel.PacketPrivacy;
WMInamespace = new ManagementScope(
String.Format(@"\\{0}\{1}",
MIIS_MachineName,
MIIS_WMI_Namespace),
connOpt
);
}
else
{
ConnectionOptions connOpt = new ConnectionOptions();
connOpt.Authentication = AuthenticationLevel.PacketPrivacy;
WMInamespace = new ManagementScope(MIIS_WMI_Namespace,connOpt);
}
try
{
// Locate the CSobject corresponding to the domain and name using
// an internal function. Display an error message if the object
// does not exist.
ManagementObject CSobject = FindCSObject(
WMInamespace,
searchDomain,
searchUser
);
if ( CSobject == null )
{
Console.WriteLine(
"Unable to find the CS object corresponding to: {0}\\{1}.",
searchDomain,
searchUser
);
return;
}
Console.WriteLine();
Console.WriteLine(
"Located CS Object for {0}\\{1}.",
searchDomain,
searchUser
);
// If the CSobject is a disconnector object, then the
// program cannot change the password.
if( CSobject["mvGuid"] == null )
{
Console.WriteLine( "The connector space object is a disconnector." );
Console.WriteLine( "The password was not set.");
return;
}
// Locate all the other CSobjects connected to that MVobject.
Console.WriteLine("Locating related connectors.");
string CSobjGUID = CSobject["mvGuid"].ToString();
string queryString = String.Format(
"Select * from MIIS_CSObject where mvGuid ='{0}'",
CSobjGUID
);
ObjectQuery MVQuery = new ObjectQuery( queryString);
ManagementObjectSearcher MVSearcher = new ManagementObjectSearcher(WMInamespace,MVQuery);
ManagementObjectCollection relatedCSObjects = MVSearcher.Get();
int relCount = GetManagementObjectCount(relatedCSObjects);
Console.WriteLine("Found {0} connectors for MV Object.", relCount);
// Enumerate through each CSObject in the collection.
Console.WriteLine("Locating MA(s) for connected CS object(s)...");
foreach (ManagementObject Connector in relatedCSObjects )
{
string Dn = Connector["Dn"].ToString();
string MaName = Connector["MaName"].ToString();
string ObjectType = Connector["ObjectType"].ToString().ToLower();
string MaType;
Console.WriteLine();
// Look for CSobjects of type 'inetorgperson' or 'user'.
if ( !(ObjectType.Equals("inetorgperson") || ObjectType.Equals("user")) )
{
Console.WriteLine(
"Wrong object type detected, Skipping {0}'s CS object:",
MaName
);
Console.WriteLine("DN : {0}.",Dn);
continue;
}
// In this example, we only want to change passwords
// for ADAM, Sun, or Netscape connected directories.
MaType = GetMATypeFromCSObject(WMInamespace,Connector);
if( !(MaType.Equals("Active Directory Application Mode (ADAM)") ||
MaType.Equals("Sun and Netscape directory servers")) )
{
Console.WriteLine("Wrong MA type detected, Skipping {0}'s CS object:",MaName);
Console.WriteLine("DN : {0}.",Dn);
Console.WriteLine("MA Type: {0}.",MaType);
continue;
}
// Set the password.
Console.WriteLine("Updating password for {0}'s CS object:", MaName);
Console.WriteLine("DN : {0}.",Dn);
Console.WriteLine("MA Type: {0}.",MaType);
string status = (string)Connector.InvokeMethod(
"SetPassword",
new string[] { newPassword }
);
if ( status.Equals("success") )
{
Console.WriteLine("Result : Successful.");
}
else
{
Console.WriteLine("Result : Failed.");
Console.WriteLine("Status : {0}",status);
}
}
}
catch(ManagementException mgmtExp)
{
Console.WriteLine("System.Management Error: {0}.",mgmtExp.Message);
}
}
// This internal function returns a ManagementObject object that
// represents the CSObject with the specified domain and username.
static ManagementObject FindCSObject(
ManagementScope WMInamespace,
string searchDomain,
string searchUser
)
{
ManagementObject CSObjectFound = null;
// Build a WMI query string for our search.
string wmiQuery = String.Format(
"Select * from MIIS_CSObject where (Domain='{0}' and Account='{1}') or " +
"(FullyQualifiedDomain='{0}' and Account='{1}') or (Domain='{0}' " +
"and UserPrincipalName='{1}') or (FullyQualifiedDomain='{0}' and UserPrincipalName='{1}')",
searchDomain,
searchUser
);
// Run the WMI query.
ObjectQuery query = new ObjectQuery(wmiQuery);
wmiQuery = null;
ManagementObjectSearcher CSsearcher = new ManagementObjectSearcher(WMInamespace,query);
ManagementObjectCollection CSobjects = CSsearcher.Get();
// The search returned an enumeration, but we only expect to get back a single
// object. Return the first object from the enumeration.
try
{
ManagementObjectCollection.ManagementObjectEnumerator Enum = CSobjects.GetEnumerator();
Enum.MoveNext();
CSObjectFound = (ManagementObject)Enum.Current;
Enum.Dispose();
}
catch
{
// Handle exceptions for the enumeration here.
}
return CSObjectFound;
}
// Returns the type of the MA that is associated with the specified CSobject.
static string GetMATypeFromCSObject(
ManagementScope WMInamespace,
ManagementObject CSObject
)
{
string MAGuid = CSObject["maGuid"].ToString();
string queryString = String.Format( "Select * from MIIS_ManagementAgent where guid = '{0}'",
MAGuid
);
ObjectQuery MAQuery = new ObjectQuery( queryString );
ManagementObjectSearcher MASearcher = new ManagementObjectSearcher(WMInamespace,MAQuery);
ManagementObjectCollection MAObjects = MASearcher.Get();
ManagementObjectCollection.ManagementObjectEnumerator Enum = MAObjects.GetEnumerator();
Enum.MoveNext();
ManagementObject MAObject = ( ManagementObject)Enum.Current;
Enum.Dispose();
return MAObject["Type"].ToString();
}
//
// This helper routine
// explicitly enumerates the ManagementObjectCollection object
// after the count property is read.
//
static int GetManagementObjectCount(ManagementObjectCollection Obj)
{
ManagementObjectCollection.ManagementObjectEnumerator Enumerator = Obj.GetEnumerator();
int count = 0;
while ( Enumerator.MoveNext() )
count++;
return count;
}
}
}
The following Visual Basic .NET example changes the password on an ADAM, Sun, or Netscape data source using System.Management namespace to invoke the WMI provider. The example has to be run by an account that is a member of the MIISPasswordSet security group.
The example has the following functions:
The main function is the start of the program. This function passes the domain name, the user name, and the new password of the accountwith the password to be setto the next function.
The SetNewPassword function sets the password of the account specified in the previous function.
The FindCSObject function searches the connector space for the object with the password that is going to be set. If the connector space exists, the function returns a ManagementObject object.
The GetMATypeFromCSObject function returns the type of management agent used to create the object with the password to set. Some connected data sources allow setting passwords on objects. The function is used to set passwords on objects from data sources that allow setting passwords.
The GetManagementObjectCount function explicitly enumerates a ManagmentObjectCollection object after the count property is read.
Option Explicit On
Imports System
Imports System.Management
Public Class SetPasswordExample
' These constants assume that this application is on the same server
' as <tla rid="fim_sync_short"/>. If this program is run from a separate computer, change
' the following constants.
' MIISPasswordSet Group member
Private Const MIIS_AccountName As String = Nothing
' Password for above account
Private Const MIIS_Password As String = Nothing
' <tla rid="fim_sync_short"/> Server name
Private Const MIIS_MachineName As String = Nothing
' WMI namespace path for the <tla rid="fim_sync_short"/> server.
Private Const MIIS_WMI_Namespace As String = "root\MicrosoftIdentityIntegrationServer"
Shared Sub Main()
' Pass the domain name, user name, and new password to the method
' that will change the password.
SetNewPassword("MIISServer", "PCUser2", "ABC!1234")
End Sub
' This method sets the password.
Private Shared Sub SetNewPassword(ByVal searchDomain As String, _
ByVal searchUser As String, _
ByVal newPassword As String)
Dim WMInamespace As ManagementScope
' Create the WMI management scope object to connect to the
' <tla rid="fim_sync_short"/> server. If the password for the MIISPasswordSet group
' member is null, then <tla rid="fim_sync_short"/> is installed on the local computer.
' Enable the PacketPrivacy Connection Option to ensure all
' communication is encrypted.
If Not (MIIS_Password Is Nothing) Then
Dim connOpt As New ConnectionOptions
connOpt.Username = MIIS_AccountName
connOpt.Password = MIIS_Password
connOpt.Authentication = AuthenticationLevel.PacketPrivacy
WMInamespace = New ManagementScope(String.Format("\\{0}\{1}", _
MIIS_MachineName, _
MIIS_WMI_Namespace), connOpt)
Else
Dim connOpt As New ConnectionOptions
connOpt.Authentication = AuthenticationLevel.PacketPrivacy
WMInamespace = New ManagementScope(MIIS_WMI_Namespace, connOpt)
End If
Try
' Locate the CSobject corresponding to the domain and name using
' an internal function. Display an error message if the object
' does not exist.
Dim CSobject As ManagementObject = FindCSObject(WMInamespace, searchDomain, searchUser)
If CSobject Is Nothing Then
Console.WriteLine("Unable to find the CS object corresponding to: {0}\{1}.", _
searchDomain, searchUser)
Return
End If
Console.WriteLine()
Console.WriteLine("Located CS Object for {0}\{1}.", searchDomain, searchUser)
' If the CSobject is a disconnector object, then the
' program cannot change the password.
If CSobject("mvGuid") Is Nothing Then
Console.WriteLine("The connector space object is a disconnector.")
Console.WriteLine("The password was not set.")
Return
End If
' Locate all the other CSobjects connected to that MVobject.
Console.WriteLine("Locating related connectors.")
Dim CSobjGUID As String = CSobject("mvGuid").ToString()
Dim queryString As String = String.Format("Select * from MIIS_CSObject where mvGuid ='{0}'", _
CSobjGUID)
Dim MVQuery As New ObjectQuery(queryString)
Dim MVSearcher As New ManagementObjectSearcher(WMInamespace, MVQuery)
Dim relatedCSObjects As ManagementObjectCollection = MVSearcher.Get()
Dim relCount As Integer = GetManagementObjectCount(relatedCSObjects)
Console.WriteLine("Found {0} connectors for MV Object.", relCount)
' Enumerate through each CSObject in the collection.
Console.WriteLine("Locating MA(s) for connected CS object(s)...")
Dim Connector As ManagementObject
For Each Connector In relatedCSObjects
Dim Dn As String = Connector("Dn").ToString()
Dim MaName As String = Connector("MaName").ToString()
Dim ObjectType As String = Connector("ObjectType").ToString().ToLower()
Dim MaType As String
Console.WriteLine()
' Look for CSobjects of type 'inetorgperson' or 'user'.
If Not (ObjectType.Equals("inetorgperson") OrElse ObjectType.Equals("user")) Then
Console.WriteLine("Wrong object type detected, Skipping {0}'s CS object:", MaName)
Console.WriteLine("DN : {0}.", Dn)
GoTo ContinueForEach1
End If
' In this example, we only want to change passwords
' for ADAM or Sun and Netscape connected directories.
MaType = GetMATypeFromCSObject(WMInamespace, Connector)
If Not (MaType.Equals("Active Directory Application Mode (ADAM)") OrElse _
MaType.Equals("Sun and Netscape directory servers")) Then
Console.WriteLine("Wrong MA type detected, Skipping {0}'s CS object:", MaName)
Console.WriteLine("DN : {0}.", Dn)
Console.WriteLine("MA Type: {0}.", MaType)
GoTo ContinueForEach1
End If
' Set the password.
Console.WriteLine("Updating password for {0}'s CS object:", MaName)
Console.WriteLine("DN : {0}.", Dn)
Console.WriteLine("MA Type: {0}.", MaType)
Dim status As String = CStr(Connector.InvokeMethod("SetPassword", _
New String() {newPassword}))
If status.Equals("success") Then
Console.WriteLine("Result : Successful.")
Else
Console.WriteLine("Result : Failed.")
Console.WriteLine("Status : {0}", status)
End If
ContinueForEach1:
Next Connector
Catch mgmtExp As ManagementException
Console.WriteLine("System.Management Error: {0}.", mgmtExp.Message)
End Try
End Sub
' This internal function returns a ManagementObject object that
' represents the CSObject with the specified domain and username.
Shared Function FindCSObject(ByVal WMInamespace As ManagementScope, _
ByVal searchDomain As String, _
ByVal searchUser As String) As ManagementObject
Dim CSObjectFound As ManagementObject = Nothing
' Build a WMI query string for our search.
Dim wmiQuery As String = String.Format("Select * from MIIS_CSObject where (Domain='{0}' and Account='{1}') or " + "(FullyQualifiedDomain='{0}' and Account='{1}') or (Domain='{0}' " + "and UserPrincipalName='{1}') or (FullyQualifiedDomain='{0}' and UserPrincipalName='{1}')", searchDomain, searchUser)
' Run the WMI query.
Dim query As New ObjectQuery(wmiQuery)
wmiQuery = Nothing
Dim CSsearcher As New ManagementObjectSearcher(WMInamespace, query)
Dim CSobjects As ManagementObjectCollection = CSsearcher.Get()
' The search returned an enumeration, but we only expect to get back a single
' object. Return the first object from the enumeration.
Try
Dim enumObject As ManagementObjectCollection.ManagementObjectEnumerator = CSobjects.GetEnumerator()
enumObject.MoveNext()
CSObjectFound = CType(enumObject.Current, ManagementObject)
enumObject.Dispose()
Catch
' Handle exceptions for the enumeration block here.
End Try
Return CSObjectFound
End Function 'FindCSObject
' Returns the type of the MA associated with the specified CSobject.
Shared Function GetMATypeFromCSObject(ByVal WMInamespace As ManagementScope, _
ByVal CSObject As ManagementObject) As String
Dim MAGuid As String = CSObject("maGuid").ToString()
Dim queryString As String
queryString = String.Format("Select * from MIIS_ManagementAgent where guid = '{0}'", MAGuid)
Dim MAQuery As New ObjectQuery(queryString)
Dim MASearcher As New ManagementObjectSearcher(WMInamespace, MAQuery)
Dim MAObjects As ManagementObjectCollection = MASearcher.Get()
Dim objectEnum As ManagementObjectCollection.ManagementObjectEnumerator = MAObjects.GetEnumerator()
objectEnum.MoveNext()
Dim MAObject As ManagementObject = CType(objectEnum.Current, ManagementObject)
objectEnum.Dispose()
Return MAObject("Type").ToString()
End Function
'
' This helper routine works explicitly enumerates the ManagementObjectCollection after the Count property has been read.
'
Shared Function GetManagementObjectCount(ByVal Obj As ManagementObjectCollection) As Integer
Dim Enumerator As ManagementObjectCollection.ManagementObjectEnumerator = Obj.GetEnumerator()
Dim count As Integer = 0
While Enumerator.MoveNext()
count += 1
End While
Return count
End Function
End Class