Monthly Archives: February 2014

PowerShell Snippet: Store Login Information Secure in PowerShell using Windows Security API

Today I want to show you a small PowerShell snippet that I created for a webinar for AvePoint. It’s a webinar in German language about the DocAve module “Content Manager”.

The snippet will show you how to store a encrypted password in a plain text file.

Therefore I use some Windows OS APIs that are accessible in .NET:

http://msdn.microsoft.com/en-us/library/system.security.cryptography.protecteddata.protect(v=vs.110).aspx

This encapsulates the “Data Protection API” of Windows: http://msdn.microsoft.com/en-us/library/ms995355.aspx

With the methods of this class you are able to encrypt and decrypt data very easily, either in the context of the current user or in the context of the local machine.

The encrypted data can only be decrypted on the same machine in the same context as where they were encrypted.

Very easy and handy. It is  NOT EASY BUT POSSIBLE to decrypt it on another machine. Just read the article mentioned above, especially the section “DPAPI Security” (http://msdn.microsoft.com/en-us/library/ms995355.aspx#windataprotection-dpapi_topic04).

It is DocAve specific but of course you can modify it for your own purpose.

Here is the Script:

<##
  Created by Ingo Karstein 
    https://blog.kenaro.com
##>

#Load Modules and Assemblies
Import-Module-Name "C:\program files\AvePoint\DocAve6\Shell\DocAveModules\DocAveModule" -DisableNameChecking
[System.Reflection.Assembly]::LoadWithPartialName("System.Security") | Out-Null

#Current folder of script
$path = Split-Path $MyInvocation.MyCommand.Path

#Config values
$docavemanageruser = "admin"
$docavemanagerserver = "kcdevsqlexch1"
$docavemanagerport = 14000

#Read password from file or get it from user and store it into a file
if( [string]::IsNullOrEmpty($docavepwd) ) {
  if( Test-Path "$($path)\pwd.txt" ) {
     $data= [System.Convert]::FromBase64String((Get-Content "$($path)\pwd.txt" -Encoding UTF8))
     $global:docavepwd = [System.Text.Encoding]::UTF8.GetString([System.Security.Cryptography.ProtectedData]::Unprotect($data, (123,54,67,89,12,32,146), "CurrentUser"))
  } else {
     $global:docavepwd = Read-Host "Enter AvePoint ""$($docavemanageruser)"" password"
     $data= [System.Security.Cryptography.ProtectedData]::Protect( ([System.Text.Encoding]::UTF8.GetBytes($docavepwd)) ,(123,54,67,89,12,32,146), "CurrentUser")

     [System.Convert]::ToBase64String($data) | Set-Content "$($path)\pwd.txt" -Encoding UTF8 -Force
  }
}

#exit if no password
if( [string]::IsNullOrEmpty($docavepwd) ) {
  exit
}

$success=$false
#check if already logged in into DocAve
try {
  $success= (Get-DALocalUser -ErrorAction 0) -ne $null 
  if( !$? ) {
    $success=$false
  }
} catch {
  $success=$false
}

#If not already logged in: Login using credentials
if( !$success ) {
  $cred = New-Object System.Management.Automation.PSCredential( $docavemanageruser, (ConvertTo-SecureString -Force -AsPlainText $docavepwd))
  Login-DAManager -ControlHost $docavemanagerserver -ControlPort $docavemanagerport -Credential $cred
  if( $? -eq $false ) {
    exit
  }
}

SharePoint 2013 People Picker error: “Sorry, we’re having trouble reaching the server.”

I have had a strange error today in my dev lab environment. First I recognized that I could not select users from the People Picker:

image

Sorry, we’re having trouble reaching the server.

Second I realized that I was not able to use any function that belongs to WCF web services such as the SharePoint REST API, e.g. at http(s)://<server>/_api/web.

Using Fiddler I found this behavior:

image

HTTP 404 NOT FOUND on /_vti_bin/client.svc/ProcessQuery

Same for /_vti_bin/client.svc/web which is the same as /_api/web.

image

Search the web I found some hints regarding this error in SharePoint. But nothing worked.

Than I created a own web service “service1.svc” with a simple method in it and placed it in folder <SP-Hive>\isapi where the virtual folder “_vti_bin” is located on the file system.

Result:  I could not call my own web service too. Same result: NOT FOUND.

Than I search the web for “WCF 404” and found some hints to “HTTP Activation” feature of Windows Server OS. Of course this was activated for .NET 3.5 and .NET 4.5.

So I deactivated the “HTTP Activation” feature of .NET 3.5 and .NET 4.5 and re-enabled one by one (1st .NET 3.5, 2nd .NET 4.5 ) them after deactivation.

image

image

image

 

After that I did a IISRESET. – Than everything works again as expected. 🙂

image

and

image