Skip to content

Instantly share code, notes, and snippets.

@gitfvb
Last active July 15, 2019 10:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gitfvb/b76ca153a8db2a5529cda07c974f8bf8 to your computer and use it in GitHub Desktop.
Save gitfvb/b76ca153a8db2a5529cda07c974f8bf8 to your computer and use it in GitHub Desktop.
EpiServer Campaign Handling via PowerShell with strong encrypted session keys and passwords
  • Needed files will be autogenerated
  • Don't forget to replace the tags in the file "epi__0__create_settings.ps1"
"<epimandant>" and "<epiapiuser>" 
################################################
#
# SCRIPT ROOT
#
################################################
# Load scriptpath
if ($MyInvocation.MyCommand.CommandType -eq "ExternalScript") {
$scriptPath = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition
} else {
$scriptPath = Split-Path -Parent -Path ([Environment]::GetCommandLineArgs()[0])
}
Set-Location -Path $scriptPath
################################################
#
# FUNCTIONS
#
################################################
# load all functions
. ".\epi__0__functions.ps1"
################################################
#
# SETTINGS
#
################################################
$pass = Read-Host -AsSecureString "Please enter the password for epi"
$passEncrypted = Get-PlaintextToSecure ((New-Object PSCredential "dummy",$pass).GetNetworkCredential().Password)
$login = @{
mandant = <epimandant>
user = "<epiapiuser>"
pass = $passEncrypted
}
$settings = @{
base="https://api.campaign.episerver.net/soap11/Rpc"
sessionFile = "session.json"
ttl = 15
encryptToken = $true
login = $login
}
################################################
#
# PACK TOGETHER SETTINGS AND SAVE AS JSON
#
################################################
# create json object
$json = $settings | ConvertTo-Json -Depth 8 # -compress
# print settings to console
$json
# save settings to file
$json | Set-Content -path "$( $scriptPath )\settings.json" -Encoding UTF8
Function Invoke-Epi {
param(
[Parameter(Mandatory=$true)][String]$webservice
,[Parameter(Mandatory=$true)][String]$method
,[Parameter(Mandatory=$false)][String[]]$param = @()
,[Parameter(Mandatory=$false)][Boolean]$useSessionId = $false
)
if ( $useSessionId ) {
# decrypt secure string
if ( $settings.encryptToken ) {
$sessionId = Get-SecureToPlaintext -String $Script:sessionId
}
# put session in params first place
$param = ,$sessionId + $param
}
$paramXML = ""
for( $i = 0 ; $i -lt $param.count ; $i++ ) {
$paramXML += "<in$( $i )>$( $param[$i] )</in$( $i )>"
}
$soapEnvelopeXml = "<?xml version=""1.0"" encoding=""utf-8""?>
<soap:Envelope xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
<soap:Body>
<$( $method )>
$( $paramXML )
</$( $method )>
</soap:Body>
</soap:Envelope>"
$header = @{
"SOAPACTION" = $method
}
$contentType = "text/xml;charset=""utf-8"""
$response = Invoke-RestMethod -Uri "$( $settings.base )$( $webservice )" -ContentType $contentType -Method Post -Verbose -Body $soapEnvelopeXml -Headers $header
$response.Envelope.Body
}
Function Get-PlaintextToSecure {
param(
[Parameter(Mandatory=$true)][String]$String
)
# generate salt
Create-KeyFile -keyfilename "aes.key" -byteLength 32
$salt = Get-Content -Path "aes.key" -Encoding UTF8
# convert
$stringSecure = ConvertTo-secureString -String $String -asplaintext -force
$return = ConvertFrom-SecureString $stringSecure -Key $salt
# return
$return
}
Function Get-SecureToPlaintext {
param(
[Parameter(Mandatory=$true)][String]$String
)
# generate salt
$salt = Get-Content -Path "aes.key" -Encoding UTF8
#convert
$stringSecure = ConvertTo-SecureString -String $String -Key $salt
$return = (New-Object PSCredential "dummy",$stringSecure).GetNetworkCredential().Password
#return
$return
}
Function Create-KeyFile {
param(
[Parameter(Mandatory=$false)][string]$keyfilename = "aes.key"
,[Parameter(Mandatory=$false)][int]$byteLength = 32
)
$keyfile = ".\$( $keyfilename )"
# file does not exist -> create one
if ( (Test-Path -Path $keyfile) -eq $false ) {
$Key = New-Object Byte[] $byteLength # You can use 16, 24, or 32 for AES
[Security.Cryptography.RNGCryptoServiceProvider]::Create().GetBytes($Key)
$Key | Set-Content -Encoding UTF8 -Path $keyfile
}
}
Function Get-EpiSession {
$sessionPath = "$( $scriptPath )\$( $settings.sessionFile )"
# if file exists -> read it and check ttl
$createNewSession = $true
if ( (Test-Path -Path $sessionPath) -eq $true ) {
$sessionContent = Get-Content -Encoding UTF8 -Path $sessionPath | ConvertFrom-Json
$expire = [datetime]::ParseExact($sessionContent.expire,"yyyyMMddHHmmss",[CultureInfo]::InvariantCulture)
if ( $expire -gt [datetime]::Now ) {
$createNewSession = $false
$Script:sessionId = $sessionContent.sessionId
}
}
# file does not exist or date is not valid -> create session
if ( $createNewSession -eq $true ) {
$expire = [datetime]::now.AddMinutes($settings.ttl).ToString("yyyyMMddHHmmss")
$pass = Get-SecureToPlaintext $settings.login.pass
$login = Invoke-Epi -webservice "Session" -method "login" -param @($settings.login.mandant, $settings.login.user, $pass)
$sessionId = $login.loginResponse.loginReturn.'#text'
if ( $settings.encryptToken ) {
$Script:sessionId = Get-PlaintextToSecure -String $sessionId
} else {
$Script:sessionId = $sessionId
}
$session = @{
sessionId=$Script:sessionId
expire=$expire
}
$session | ConvertTo-Json | Set-Content -Encoding UTF8 -Path $sessionPath
}
}
<#
https://world.episerver.com/documentation/developer-guides/campaign/SOAP-API/introduction-to-the-soap-api/webservice-overview/
WSDL: https://api.campaign.episerver.net/soap11/RpcSession?wsdl
#>
################################################
#
# SCRIPT ROOT
#
################################################
# Load scriptpath
if ($MyInvocation.MyCommand.CommandType -eq "ExternalScript") {
$scriptPath = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition
} else {
$scriptPath = Split-Path -Parent -Path ([Environment]::GetCommandLineArgs()[0])
}
Set-Location -Path $scriptPath
################################################
#
# SETTINGS
#
################################################
# Load settings
$settings = Get-Content -Path "$( $scriptPath )\settings.json" -Encoding UTF8 -Raw | ConvertFrom-Json
################################################
#
# FUNCTIONS
#
################################################
# load all functions
. ".\epi__0__functions.ps1"
################################################
#
# PROGRAM
#
################################################
#-----------------------------------------------
# SESSION
#-----------------------------------------------
Get-EpiSession
#-----------------------------------------------
# MAILINGs
#-----------------------------------------------
$mailings = Invoke-Epi -webservice "Mailing" -method "getIdsInStatus" -param @("campaign", "ACTIVATION_REQUIRED") -useSessionId $true
$smartCampaigns = $mailings.multiRef.'#text'
$smartCampaigns
$mailingsDetails = @{}
$smartCampaigns | ForEach {
$mailingId = $_
$mailingsDetail = Invoke-Epi -webservice "Mailing" -method "getName" -param @($mailingId) -useSessionId $true
$mailingsDetails.Add($mailingId, $mailingsDetail.getNameResponse.getNameReturn.'#text')
}
$mailingsDetails
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment