Installing FIM Automation PowerShell cmdlets

We all need to install FIM Automation cmdlets on different server/client at some stage, why on earth Microsoft didn’t make this easier I will never know. But again in true Ninja fashion I have automated the install in PowerShell……Peep this!

#Make sure the Microsoft.ResourceManagement.dll, Microsoft.ResourceManagement.Automation.dll and the Microsoft.IdentityManagement.Logging.dll are all in the current directory.
set-alias installutil $env:windir\Microsoft.NET\Framework\v2.0.50727\installutil
installutil .\Microsoft.ResourceManagement.Automation.dll
$installdir = "C:\Install"
Set-location $installdir
[System.Reflection.Assembly]::Load("System.EnterpriseServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
$publish = New-Object System.EnterpriseServices.Internal.Publish
$publish.GacInstall($installdir + "\Microsoft.ResourceManagement.dll")
$publish.GacInstall($installdir +"\Microsoft.IdentityManagement.Logging.dll")
#The following lines remove the MIM dll's out of the GAC if required at some later stage.
#$publish.GacRemove($installdir + "\Microsoft.ResourceManagement.dll")
#$publish.GacRemove($installdir +"\Microsoft.IdentityManagement.Logging.dll")

Disable LoopBack Check

Common problem with deployments on SharePoint is that when you try to browse to the server loopback on any dns name that isn’t the server name itself the server will stop you and it looks like a Kerberos error initially. To disable these checks can be done easily and in true Ninja fashion by PowerShell script….check it out:

The first option is more secure as you only grant access to the host names specified, the second option gives access to the server on any hostname so is less secure.

 

New-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0 -Name BackConnectionHostNames -Value "password.mim.ninja","portal.mim.ninja" -PropertyType MultiString -Force

New-ItemProperty HKLM:\System\CurrentControlSet\Control\Lsa -Name "DisableLoopbackCheck" -value "1" -PropertyType dword

 

You can have as many host names as you like in the first script, MS recommends only using the 2nd option in development environments.

Connecting to a SAP WebService with Powershell

Now, the title says SAP but this works for any WebService but the datatypes returned will be different. I was surprised how easy and powerful this is I was recently working on a SAP project so I knocked together a quick Powershell POC script to troubleshoot some problems I was having. You could use a script like this in the MIMWAL workflow or in a Powershell Management agent if coding an extensible MA gives you shudders and you need to connect to a SAP system via WebServices.

So you need your WSDL url or file before you begin and an idea of some of the Datatypes and functions/methods sat behind that the below example is using a couple of custom functional BAPI’s created this will be different to your particular environment.

$webSites = get-WebSite
$global:index=-1
$webSites |  Format-Table -Property @{name="index";expression={$global:index;$global:index+=1}},name
$sitenameindex = read-host -Prompt "Enter Site index"
$sitename = $webSites[$sitenameindex].name

try
{
$RuleName = "HTTPS Redirect"
$Rule = @{
 Name = $RuleName
 patternSyntax = 'ECMAScript'
 stopProcessing = 'True'
 match = @{
  url = '(.*)'
  ignoreCase = 'True'
  negate = 'False'
 }
 conditions = @{
  logicalGrouping = 'MatchAll'
  trackAllCaptures = 'True'
 }
 action = @{
  type = 'Redirect'
  url = 'https://{HTTP_HOST}/{R:1}'
  appendQueryString = 'False'
  redirectType = 'Permanent'
 }
}
Add-WebConfigurationProperty -PSPath "IIS:\Sites\$SiteName" -Filter "/system.webServer/rewrite/rules" -Name "." -Value $Rule 
$match = @{
 input = '{HTTPS}'
 matchType = 'Pattern'
 pattern = 'off'
 ignoreCase = 'True'
 negate = 'False'
}
Add-WebConfigurationProperty -PSPath "IIS:\Sites\$SiteName" -Filter "/system.webServer/rewrite/rules/rule[@Name='$RuleName']/conditions" -Name "." -Value $match


$RuleName = "Redirect to MIM Site"
$Rule = @{
 Name = $RuleName
 patternSyntax = 'ECMAScript'
 stopProcessing = 'True'
 match = @{
  url = '^$'
  ignoreCase = 'True'
  negate = 'False'
 }
 action = @{
  type = 'Redirect'
  url = '/IdentityManagement/default.aspx'
  appendQueryString = 'False'
  redirectType = 'Permanent'
 }
}
Add-WebConfigurationProperty -PSPath "IIS:\Sites\$SiteName" -Filter "/system.webServer/rewrite/rules" -Name "." -Value $Rule
}
catch
{
Write-Host "There was a problem............." -ForegroundColor Red
write-host $_.Exception.Message -ForegroundColor Red
exit
}
Write-Host "$sitename has been updated successfully...........Enjoy!" -ForegroundColor Green




This is a very simple example that shows how easy it is with some custom function SAP BAPI’s created, now it would be even easier if there was one function that returned the user details in one go. I would always insist on this if I was doing a project for a customer. However that inevitably requires external resource of a SAP consultant so becomes problematic, the default SAP BAPI’s are horrendously complicated with nested data tables and multiple calls so try and avoid them like the plague.

The Microsoft documentation on this subject is pretty good for a change and can be found here.

Errors running Azure PowerShell cmdlets in MIMWAL workflow

 

Just a quick one as this has been discussed on the net before but if you are trying to run Azure PowerShell cmdlets in a MIMWAL workflow or embedded in a custom work flow and get the below error:

Import-Module : Could not load file or assembly ‘file:///C:\Windows\system32\WindowsPowerShell\v1.0\Modules\MSOnline\Microsoft.Online.Administration.Automation.PSModule.dll’ or one of its dependencies. This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded.

This is because the MIMWAL is built on the .net framework 3.5 whereas the later Azure PowerShell cmdlets are built on .net 4, if you can live with the older functionality the easy fix is to install version 1 of the cmdlets 64 bit from here or here for the 32 bit versions these are build 8362.1 so getting a bit old but have most of the required functionality. The whole list of versions is here but anything later than 8362.1 will not work. The other option is to take your script out of the workflow and trigger it externally.

MIM HTTPS redirect and Site Pages redirect

Everyone always needs to do this right? I used to do this with a SharePoint homepage but using the URL Rewrite module is a much neater solution and portable. So, URL Rewrite is an addon module that you can add from the Web Platform Installer here. Install that and search for URL Rewrite and install it.

Then use the below powershell code to add https and redirect to your mim site, the script will query all the sites then ask you to enter an index corresponding to the site…..Macho Ninja!

$webSites = get-WebSite
$global:index=-1
$webSites |  Format-Table -Property @{name="index";expression={$global:index;$global:index+=1}},name
$sitenameindex = read-host -Prompt "Enter Site index"
$sitename = $webSites[$sitenameindex].name

try
{
$RuleName = "HTTPS Redirect"
$Rule = @{
 Name = $RuleName
 patternSyntax = 'ECMAScript'
 stopProcessing = 'True'
 match = @{
  url = '(.*)'
  ignoreCase = 'True'
  negate = 'False'
 }
 conditions = @{
  logicalGrouping = 'MatchAll'
  trackAllCaptures = 'True'
 }
 action = @{
  type = 'Redirect'
  url = 'https://{HTTP_HOST}/{R:1}'
  appendQueryString = 'False'
  redirectType = 'Permanent'
 }
}
Add-WebConfigurationProperty -PSPath "IIS:\Sites\$SiteName" -Filter "/system.webServer/rewrite/rules" -Name "." -Value $Rule 
$match = @{
 input = '{HTTPS}'
 matchType = 'Pattern'
 pattern = 'off'
 ignoreCase = 'True'
 negate = 'False'
}
Add-WebConfigurationProperty -PSPath "IIS:\Sites\$SiteName" -Filter "/system.webServer/rewrite/rules/rule[@Name='$RuleName']/conditions" -Name "." -Value $match


$RuleName = "Redirect to MIM Site"
$Rule = @{
 Name = $RuleName
 patternSyntax = 'ECMAScript'
 stopProcessing = 'True'
 match = @{
  url = '^$'
  ignoreCase = 'True'
  negate = 'False'
 }
 action = @{
  type = 'Redirect'
  url = '/IdentityManagement/default.aspx'
  appendQueryString = 'False'
  redirectType = 'Permanent'
 }
}
Add-WebConfigurationProperty -PSPath "IIS:\Sites\$SiteName" -Filter "/system.webServer/rewrite/rules" -Name "." -Value $Rule
}
catch
{
Write-Host "There was a problem............." -ForegroundColor Red
write-host $_.Exception.Message -ForegroundColor Red
exit
}
Write-Host "$sitename has been updated successfully...........Enjoy!" -ForegroundColor Green


The reference for the re-write module is here. Be careful when using permamnent as your redirectType though if you are testing this out it may be worth using temporary as when you use Permanent the rule sticks even when you restart/hard refresh the browser. You either have to clear your cache or start in private browsing for the new change to appear which took me a while to work out why my perfectly corrected rule was still using an old incorrect rule when debugging.

WordPress Appliance - Powered by TurnKey Linux