I am currently working on doing some implementations using the great Granfeldt Powershell MA.
I have schema, import and export working, but face a problem with export when I want to use attributes in connectorspace to perform something, not just updating. Like for executing a powershell command, where I need both the userprincipalname and the location,
or something like that.
I have created a simple example MA just for the purpose of testing this issue. It manages ContactInformation from a database (email, phone) and accepts the first and lastname back from the FIM metaverse from other source. I use the latest Powershell MA.
The problem is in export.ps1 (shown later in this post), in the line that says...:
$ExternalEmail = $_.ExternalEmail
I would expect this value to be filled with the value from the connectorspace, but it is just blank. There is a value in there, this is not the first time it runs or anything like that. I see the same approach used in the Lync samples for Powershell MA,
so I assume I am doing something wrong somewhere else.
Can you please help by telling me what I am doing wrong?
This is the pending export I test with:
Database:
schema.ps1
$obj = New-Object -Type PSCustomObject
$obj | Add-Member -Type NoteProperty -Name "Anchor-EmployeeId|String" -Value "000000"
$obj | Add-Member -Type NoteProperty -Name "objectClass|String" -Value "user"
$obj | Add-Member -Type NoteProperty -Name "Phone|String" -Value "+99 9999999"
$obj | Add-Member -Type NoteProperty -Name "ExternalEmail|String" -Value "some@email.com"
$obj | Add-Member -Type NoteProperty -Name "LastName|String" -Value "firstname"
$obj | Add-Member -Type NoteProperty -Name "FirstName|String" -Value "lastname"
$obj | Add-Member -Type NoteProperty -Name "CreatedOn|String" -Value "2016-04-06 13:46"
$obj | Add-Member -Type NoteProperty -Name "ModifiedOn|String" -Value "2016-04-06 13:47"
$obj
import.ps1
param (
$Username,
$Password,
$OperationType
)
$DebugFilePath = "C:\PSMA\ContactInfo\ImportDebug.txt"
if(!(Test-Path $DebugFilePath))
{$DebugFile = New-Item -Path $DebugFilePath -ItemType File}
else
{$DebugFile = Get-Item -Path $DebugFilePath}"Starting Import : " + (Get-Date) | Out-File $DebugFile -Append
$ConnectionString = "Data Source=localhost;Initial Catalog=TestDatabase;Integrated Security=True";
$Connection = New-Object System.Data.SQLClient.SQLConnection
$Connection.ConnectionString = $ConnectionString
$Connection.Open()
$Command = New-Object System.Data.SQLClient.SQLCommand
$Command.Connection = $Connection
$SQL = "SELECT * FROM ContactInfo"
$Command.CommandText = $SQL
$Reader = $Command.ExecuteReader()
While ($Reader.Read())
{
$obj = @{}
$obj.Add("objectClass", "user")
$obj.Add("EmployeeId", $Reader[“EmployeeId”])
$obj.Add("Phone", $Reader[“Phone”])
$obj.Add("ExternalEmail", $Reader[“ExternalEmail”])
$obj.Add("FirstName", $Reader[“FirstName”])
$obj.Add("LastName", $Reader[“LastName”])
$obj.Add("ModifiedOn", $Reader[“ModifiedOn”].ToString("o"))
$obj.Add("CreatedOn", $Reader[“CreatedOn”].ToString("o"))
$obj
}
$Connection.Close()
export.ps1 (most of which is debug code)
param (
$Username,
$Password
)
BEGIN
{
#Writing Start tag in Debug File.
$DebugFilePath = "C:\PSMA\ContactInfo\ExportDebug.txt"
if(!(Test-Path $DebugFilePath))
{$DebugFile = New-Item -Path $DebugFilePath -ItemType File}
else
{$DebugFile = Get-Item -Path $DebugFilePath}
"Starting Export : " + (Get-Date) | Out-File $DebugFile -Append
}
PROCESS
{
#Initialize Parameters
$Identifier = $_.Identifier
$EmployeeId = $_.DN
$FirstName = $_.FirstName
$ExternalEmail = $_.ExternalEmail
"Firstname: '" + $Firstname + "' " + (Get-Date) | Out-File $DebugFile -Append"ExternalEmail: '" + $ExternalEmail + "' " + (Get-Date) | Out-File $DebugFile -Append
$ErrorName = "success"
$ErrorDetail = $null
$date = Get-Date -Format "yyyy-MM-dd""Processing : " + $_.DN | Out-File $DebugFile -Append"No of Changes : " + $_.ChangedAttributeNames.Count | Out-File $DebugFile -Append
#Loop through changes and update parameters
foreach ($can in $_.ChangedAttributeNames)
{# $can : ChangedAttributeName
foreach ($ValueChange in $_.AttributeChanges[$can].ValueChanges)
{
if ( $can -eq 'FirstName' ){$FirstName = $ValueChange.Value}
if ( $can -eq 'LastName' ){$LastName = $ValueChange.Value}
}
}
"Firstname: '" + $Firstname + "' " + (Get-Date) | Out-File $DebugFile -Append #Now has a value, if the attribute changed"LastName: '" + $LastName + "' " + (Get-Date) | Out-File $DebugFile -Append #Now has a value if the attribute changed
#Verify changetype.
if ($_.ObjectModificationType -eq 'Add')
{
throw "Add modification are not supported"
}
if ($_.ObjectModificationType -eq 'Delete')
{
throw "Delete modification are not supported"
}
#Supported ChangeType is Replace
if ($_.ObjectModificationType -match 'Replace')
{
$ConnectionString = "Data Source=localhost;Initial Catalog=MiisInput;Integrated Security=True";
$Connection = New-Object System.Data.SQLClient.SQLConnection
$Connection.ConnectionString = $ConnectionString
$Connection.Open()
$Command = New-Object System.Data.SQLClient.SQLCommand
$Command.Connection = $Connection
$SQL = "UPDATE ContactInfo SET LastName = @LastName, FirstName = @FirstName, ModifiedOn = GETDATE() WHERE EmployeeId = @EmployeeId"
$Command.CommandText = $SQL
$Command.Parameters.Add("@EmployeeId", [System.Data.SqlDbType]::VarChar, 50) | Out-Null
$Command.Parameters.Add("@LastName", [System.Data.SqlDbType]::VarChar, 50) | Out-Null
$Command.Parameters.Add("@FirstName", [System.Data.SqlDbType]::VarChar, 50) | Out-Null
$Command.Parameters[0].Value = $EmployeeId
$Command.Parameters[1].Value = $LastName
$Command.Parameters[2].Value = $FirstName
$Command.ExecuteNonQuery() | Out-Null
$Connection.Close()
}
#Return the result to the MA
$obj = @{}
$obj.Add("[Identifier]",$Identifier)
$obj.Add("[ErrorName]",$ErrorName)
if($ErrorDetail){$obj.Add("[ErrorDetail]",$ErrorDetail)}
$obj
}
END
{
"Ending Export : " + (Get-Date) | Out-File $DebugFile -Append
}