Thursday, November 23, 2017

Installing workflow manager on sharepoint 2016

Scenario:
Sharepoint 2016 needs workflow supports since 2010 workflows now seems dead.
This needs to be done offline

Overview of steps

  1. Download all programs from internet-enabled client with getOfflinePackages
  2. Install packages on server in correct order
  3.  Configure workflow manager
  4.  Register workflow service in sharepoint

Step 1 - Download necessary files for offlineinstallationen

On client with webaccess
  1. Install WebPlattformInstaller
  2. Download packages with getOfflinePackages.ps1
  3. $products = "ServiceBus,ServiceBusCU1,WorkflowCU4,WorkflowManagerRefresh,WorkflowClientCU4"
    $scriptPath = $(split-path -Parent $MyInvocation.MyCommand.Definition)
    start-process -FilePath 'C:\Program Files\Microsoft\Web Platform Installer\webpicmd.exe' -ArgumentList "/offline /products:$($products) /path:$scriptPath\WebPlattFormFiles" -NoNewWindow -PassThru -wait

Step 2 - Install packages on server in correct order

  1. Install packages with InstallWFM.ps1 to get correct order
    $scriptPath = $(split-path -Parent $myinvocation.MyCommand.Definition)
    #1 servicebus
    start-process -FilePath 'C:\Program Files\Microsoft\Web Platform Installer\webpicmd.exe' -ArgumentList "/install /products:ServiceBus /xml:$($scriptPath)\WebPlattFormFiles\feeds\latest\webproductlist.xml /AcceptEula /suppressPostFinish" -wait -passthru
    #2 service bus updates
    start-process -FilePath 'C:\Program Files\Microsoft\Web Platform Installer\webpicmd.exe' -ArgumentList "/install /products:ServiceBusCU1 /xml:$($scriptPath)\WebPlattFormFiles\feeds\latest\webproductlist.xml /AcceptEula /suppressPostFinish"
    #3 workflowmanager client
    start-process -FilePath 'C:\Program Files\Microsoft\Web Platform Installer\webpicmd.exe' -ArgumentList "/install /products:WorkflowClientCU4 /xml:$($scriptPath)\WebPlattFormFiles\feeds\latest\webproductlist.xml /AcceptEula /suppressPostFinish"
    #4 workflowmanagerrefresh
    start-process -FilePath 'C:\Program Files\Microsoft\Web Platform Installer\webpicmd.exe' -ArgumentList "/install /products:WorkflowManagerRefresh /xml:$($scriptPath)\WebPlattFormFiles\installers\WorkflowManagerRefresh\feeds\latest\webproductlist.xml /AcceptEula /suppressPostFinish"
    #5 workflowmanager updates
    start-process -FilePath 'C:\Program Files\Microsoft\Web Platform Installer\webpicmd.exe' -ArgumentList "/install /products:WorkflowCU4 /xml:$($scriptPath)\WebPlattFormFiles\feeds\latest\webproductlist.xml /AcceptEula /suppressPostFinish"
    view raw InstallWfm.ps1 hosted with ❤ by GitHub

Step 3 - Configure Workflow Manager

  1. Update wfmconfig.xml with credentials and databasename
  2. Configure with configureWFM.ps1
    function WFM-Configure {
    param (
    $dbServer,
    $dbPrefix,
    $spServiceAcctName,
    $spServiceAcctPwd,
    $spAdminAcct,
    $passphrase
    )
    # Create new SB Farm
    $SBCertificateAutoGenerationKey = ConvertTo-SecureString -AsPlainText -Force -String $passphrase;
    $WFCertAutoGenerationKey = ConvertTo-SecureString -AsPlainText -Force -String $passphrase;
    $managementCS = 'Data Source=' + $dbServer + ';Initial Catalog=' + $dbPrefix + '_WFMSB_Management;Integrated Security=True;Encrypt=False';
    $gatewayCS = 'Data Source=' + $dbServer + ';Initial Catalog=' + $dbPrefix + '_WFMSB_Gateway;Integrated Security=True;Encrypt=False';
    $messageContCS = 'Data Source=' + $dbServer + ';Initial Catalog=' + $dbPrefix + '_WFMSB_MessageContainer;Integrated Security=True;Encrypt=False';
    Write-Host -ForegroundColor White ' - Creating new Service Bus farm...' -NoNewline;
    try {
    $sbFarm = Get-SBFarm -SBFarmDBConnectionString $managementCS;
    Write-Host -ForegroundColor White 'Already Exists';
    }
    catch {
    New-SBFarm -SBFarmDBConnectionString $managementCS -InternalPortRangeStart 9000 -TcpPort 9354 -MessageBrokerPort 9356 -RunAsAccount $spServiceAcctName -AdminGroup 'BUILTIN\Administrators' -GatewayDBConnectionString $gatewayCS -CertificateAutoGenerationKey $SBCertificateAutoGenerationKey -MessageContainerDBConnectionString $messageContCS;
    Write-Host -ForegroundColor White 'Done';
    }
    # Create new WF Farm
    Write-Host -ForegroundColor white " - Creating new Workflow Farm..." -NoNewline;
    $wfManagementCS = 'Data Source=' + $dbServer + ';Initial Catalog=' + $dbPrefix + '_WFM_Management;Integrated Security=True;Encrypt=False';
    $wfInstanceCS = 'Data Source=' + $dbServer + ';Initial Catalog=' + $dbPrefix + '_WFM_InstanceManagement;Integrated Security=True;Encrypt=False';
    $wfResourceCS = 'Data Source=' + $dbServer + ';Initial Catalog=' + $dbPrefix + '_WFM_ResourceManagement;Integrated Security=True;Encrypt=False';
    try {
    $wfFarm = Get-WFFarm -WFFarmDBConnectionString $wfManagementCS;
    Write-Host -ForegroundColor White 'Already Exists';
    }
    catch {
    New-WFFarm -WFFarmDBConnectionString $wfManagementCS -RunAsAccount $spServiceAcctName -AdminGroup 'BUILTIN\Administrators' -HttpsPort 12290 -HttpPort 12291 -InstanceDBConnectionString $wfInstanceCS -ResourceDBConnectionString $wfResourceCS -CertificateAutoGenerationKey $WFCertAutoGenerationKey; #changed admingroup
    Write-Host -ForegroundColor white 'Done';
    }
    # Add SB Host
    Write-Host -ForegroundColor white ' - Adding Service Bus host...' -NoNewline;
    try {
    $SBRunAsPassword = ConvertTo-SecureString -AsPlainText -Force -String $spServiceAcctPwd;
    #Add-SBHost -SBFarmDBConnectionString $managementCS -RunAsPassword $SBRunAsPassword -EnableHttpPort -EnableFirewallRules $true -CertificateAutoGenerationKey $SBCertificateAutoGenerationKey; #removed enablehttpport
    Add-SBHost -SBFarmDBConnectionString $managementCS -RunAsPassword $SBRunAsPassword -EnableFirewallRules $true -CertificateAutoGenerationKey $SBCertificateAutoGenerationKey;
    Write-Host -ForegroundColor white 'Done';
    }
    catch {
    Write-Host -ForegroundColor white 'Already Exists';
    #write-warning "Error was $($_.exception)"
    }
    Write-Host -ForegroundColor white ' - Creating Workflow Default Namespace...' -NoNewline;
    $sbNamespace = $dbPrefix + '-WorkflowNamespace';
    try {
    $defaultNS = Get-SBNamespace -Name $sbNamespace -ErrorAction SilentlyContinue;
    Write-Host -ForegroundColor white 'Already Exists';
    }
    catch {
    try {
    # Create new SB Namespace
    $currentUser = $env:userdomain + '\' + $env:username;
    #New-SBNamespace -Name $sbNamespace -AddressingScheme 'Path' -ManageUsers $spServiceAcctName,$spAdminAcctName,$currentUser; #replaced spAdminAcctName with spadminAcct
    New-SBNamespace -Name $sbNamespace -AddressingScheme 'Path' -ManageUsers $spServiceAcctName,$spAdminAcct,$currentUser;
    Start-Sleep -s 90
    Write-Host -ForegroundColor white 'Done';
    }
    catch [system.InvalidOperationException] {
    throw;
    }
    }
    # Get SB Client Configuration
    $SBClientConfiguration = Get-SBClientConfiguration -Namespaces $sbNamespace;
    # Add WF Host
    try {
    $WFRunAsPassword = ConvertTo-SecureString -AsPlainText -Force -String $spServiceAcctPwd;
    Write-Host -ForegroundColor White ' - Adding Workflow Host...' -NoNewline;
    Add-WFHost -WFFarmDBConnectionString $wfManagementCS `
    -RunAsPassword $WFRunAsPassword -EnableFirewallRules $true `
    -SBClientConfiguration $SBClientConfiguration -CertificateAutoGenerationKey $WFCertAutoGenerationKey;
    Write-Host -ForegroundColor White 'Done';
    }
    catch {
    Write-Host -ForegroundColor white "Already Exists";
    }
    }
    Import-Module WorkflowManager -ErrorAction SilentlyContinue
    $scriptPath = $(split-path -Parent $myinvocation.MyCommand.Definition)
    [xml]$wmfConfig = get-content -Path "$scriptPath\wfmConfig.xml"
    WFM-Configure -dbServer $wmfConfig.configuration.dbserver -dbPrefix $wmfConfig.configuration.dbprefix -spServiceAcctName $wmfConfig.configuration.spServiceAcctName -spServiceAcctPwd $wmfConfig.configuration.spServiceAcctPwd -spAdminAcct $wmfConfig.configuration.spAdminAcct -passphrase $wmfConfig.configuration.passphrase
    <configuration>
    <dbserver>sp2016</dbserver>
    <dbprefix>WFM</dbprefix>
    <spServiceAcctName>mycompany\workflowaccount</spServiceAcctName>
    <spServiceAcctPwd>mypassword</spServiceAcctPwd>
    <spAdminAcct>mycompany\spinstall</spAdminAcct>
    <passphrase>mypassphrase</passphrase>
    </configuration>
    view raw wfconfig.xml hosted with ❤ by GitHub
  3. Update siteaddress and run registerWFOnsite
    Add-PSSnapin microsoft.sharepoint.powershell -ErrorAction SilentlyContinue
    Import-Module WorkflowManager -ErrorAction SilentlyContinue
    Register-SPWorkflowService -SPSite "https://site.mycompany.com" -WorkflowHostUri "https://site.mycompany.com:12290"
    $wms = Get-SPWorkflowServiceApplicationProxy
    $wms.RegisterWorkflowLifecycleManagementEnvironment()
    view raw gistfile1.txt hosted with ❤ by GitHub
References:
https://www.helloitsliam.com/2014/11/06/sharepoint-2013-workflow-manager-woes/ - source for the order of installation
http://blog.robgarrett.com/2014/05/12/install-workflow-manager-with-powershell/ - original script for configuring workflow manager
https://blogs.msdn.microsoft.com/laleh/2014/09/03/sharepoint-2013-workflow-troublehsooting/ - troubleshooting workflow manager
https://social.technet.microsoft.com/wiki/contents/articles/34407.sharepoint-2016-step-by-step-installation-of-workflow-manager.aspx - another installationguide
https://knowledge.zomers.eu/SharePoint/Pages/How-to-install-and-configure-Workflow-Manager-on-Windows-2012-R2.aspx - more updated information on how to configure worklow manager
https://docs.microsoft.com/en-us/iis/install/web-platform-installer/web-platform-installer-direct-downloads - webplattforminstaller

Monday, November 20, 2017

Sharepoint and alternate languages

So what happens when a column is created and then changed.
And then, possible, changed again in an alternate language?

First created, staticName is set and the cultured name
image
When names is changed, only the culturename is changed
clip_image001
When and alternate language is added, and copy of the culturename appears.
image
When name is changed again to doktor2, only the current language version is changed. Swedish 1053.
clip_image001[6]
Now we have 3 version to manage.
When we choose overwrite language specific version the values dont change.
clip_image002
When we now change the column to Doktor3, only the 1053 version change when we’re using the alternate languagebrowser.
clip_image003
But if we change using the default language (1033) to doktor4, all local variants are overwritten
clip_image004
But then a local editor is at it again, setting doktor5 in swedish and the values are off.
clip_image005
But what happens if we now remove local variants? Then we're down to only the default columns
clip_image006
Changing from swedish gui to doktor6 and the english 1033 is changed.
clip_image007
But what happens if language is enabled again? Well, the old value is still there…
clip_image008
The lesson here?
Stay away from alternate languages!
And also a fun script for checking all the versions of a fields on a list.


Add-PSSnapin microsoft.sharepoint.powershell
$websiteUrl = "https://sharepoint.mycompany.com/sites/test2"
$listName = "LanguageList"
$web = get-spweb $websiteUrl
$cultures = $web.SupportedUICultures
$objects = @()
foreach ($culture in $cultures) {
[Threading.Thread]::CurrentThread.CurrentUICulture = $culture
write-output "Passing $($web.url) with culture $($culture.DisplayName) ($($culture.lcid))"
$list = $web.Lists[$listName]
if ($list -ne $null) {
foreach ($field in $list.Fields) {
$tempObject = new-object PSObject -Property @{staticName=$field.StaticName;culture=$culture.LCID;title=$field.Title}
$objects +=$tempObject
}
}
else {write-output "Can't find list: $listName"}
}
$objects |sort-object -Property staticName
foreach ($lang in ($objects|select culture -Unique -ExpandProperty culture)) {
write-output "Number of variants For LCID $($lang): $(($objects|where-object {$_.culture -like $lang}).count)"
}
write-output "`nSelected values:"
$objects |where-object {$_.staticName -like "Title" -or $_.staticName -like "Doktor"} |format-table

Powershell and Uptimerobot

Uptimerobot can be quite tedious when you need to update many monitors at once. For example say you bought the license for Uptimerobot and n...