Adding a deployment step to call a http endpoint in Octopus Deploy - octopus-deploy

I am trying to create a new Octopus deploy step, which will call a http endpoint.
I have found the following step type that seems promising, but can get any documentation on it:
"Http Json Value Check
Gets json from http endpoint, looks-up a value by key and checks that it matches a predefined value. If value matches then script exists with a success code, if value does not match then script exists with a failure code."
I am not sure what to enter for the:
"Json Key" and the "Expected Value"
Has anyone done this? have an example or suggest a different method to achieve what I am trying?

Here is a PowerShell script I use to get the JSON from an endpoint and check for a valid Value. If I could remember where I got the code base before I modified it a little I would give credit to the original author. It will work with either a string or a regex.
#-------------------------------------------------------------------------
# Warmup.ps1
#-------------------------------------------------------------------------
[int]$returnme = 0
[int]$SleepTime = 5
[string]$regex = '[>"]?[aA]vailable["<]?'
[string]$strContains = $regex
# [string]$strContains = "log in"
[string]$hostName = hostname
[string]$domainName = (Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Filter IPEnabled=TRUE -ComputerName .).DNSDomain
[string]$warmMeUp = "http://$hostName.$domainName/endpoint"
[string]$html = "Will Be Set Later"
#-------------------------------------------------------------------------
# Get-WebPage
#-------------------------------------------------------------------------
function Get-WebPage([string]$url)
{
try
{
$wc = new-object net.webclient;
$wc.credentials = [System.Net.CredentialCache]::DefaultCredentials;
[string]$pageContents = $wc.DownloadString($url);
$wc.Dispose();
}
catch
{
Write-Host "First Try Failed. Second Try in $SleepTime Seconds."
try
{
Start-Sleep -s $SleepTime
$wc = new-object net.webclient;
$wc.credentials = [System.Net.CredentialCache]::DefaultCredentials;
$pageContents = $wc.DownloadString($url);
$wc.Dispose();
}
catch
{
$pageContents = GetWebSiteStatusCode($url)
}
}
return $pageContents;
}
#-------------------------------------------------------------------------
# GetWebSiteStatusCode
#-------------------------------------------------------------------------
function GetWebSiteStatusCode
{
param (
[string] $testUri,
[int] $maximumRedirection = 5
)
$request = $null
try {
$request = Invoke-WebRequest -Uri $testUri -MaximumRedirection $maximumRedirection -ErrorAction SilentlyContinue
}
catch [System.Net.WebException] {
$request = $_.ErrorDetails.Message
}
catch {
Write-Error $_.Exception
return $null
}
return $request
}
#-------------------------------------------------------------------------
# Main Application Logic
#-------------------------------------------------------------------------
"Warming up '{0}'..." -F $warmMeUp;
$html = Get-WebPage -url $warmMeUp;
Write-Host "Looking for Pattern $strContains"
if ($html.ToLower().Contains("unavailable") -or !($html -match $strContains))
{
$returnme = -1
Write-Host "Warm Up Failed. html returned:`n" + $html
}
exit $returnme

Related

Using Powershell to get a list of users who have logged into a machine in the past year

We have a few computers that are used in a lab for processing and users can log in directly on-site or via remote desktop. We are trying to clean up the machines and decided to remove user folders for those who have not logged on in the past year. I am able to use windows event viewer to find the information, but I haven't figured out a way to export the information I need.
I found this script which seems to do exactly what I need, except I'm getting the following error when I run it: https://github.com/adbertram/Random-PowerShell-Work/blob/master/ActiveDirectory/Get-UserLogonSessionHistory.ps1
PS C:\Users\vmc\Documents> .\userevents.ps1
Get-WinEvent : Could not retrieve information about the Security log. Error: Attempted to perform an unauthorized
operation..
At C:\Users\vmc\Documents\userevents.ps1:48 char:29
+ ... ($events = Get-WinEvent -ComputerName $computer -LogName $logNames - ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-WinEvent], Exception
+ FullyQualifiedErrorId : LogInfoUnavailable,Microsoft.PowerShell.Commands.GetWinEventCommand
Get-WinEvent : There is not an event log on the BIGBERTHA computer that matches "Security".
At C:\Users\vmc\Documents\userevents.ps1:48 char:29
+ ... ($events = Get-WinEvent -ComputerName $computer -LogName $logNames - ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Security:String) [Get-WinEvent], Exception
+ FullyQualifiedErrorId : NoMatchingLogsFound,Microsoft.PowerShell.Commands.GetWinEventCommand
C:\Users\vmc\Documents\userevents.ps1 : A positional parameter cannot be found that accepts argument '.'.
At line:1 char:1
+ .\userevents.ps1
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [userevents.ps1], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,userevents.ps1
I do have a log called 'Security' when I look at the Windows Event Viewer, so I'm not sure why I can't query this log?
Thank you for any help- suggestions to get this script to run or another way to compile this list are very much appreciated!
Script from the link (saved to userevents.ps1, called from powershell above)
<#
.SYNOPSIS
This script finds all logon, logoff and total active session times of all users on all computers specified. For this script
to function as expected, the advanced AD policies; Audit Logon, Audit Logoff and Audit Other Logon/Logoff Events must be
enabled and targeted to the appropriate computers via GPO or local policy.
.EXAMPLE
.PARAMETER ComputerName
An array of computer names to search for events on. If this is not provided, the script will search the local computer.
.INPUTS
None. You cannot pipe objects to Get-ActiveDirectoryUserActivity.ps1.
.OUTPUTS
None. If successful, this script does not output anything.
#>
[CmdletBinding()]
param
(
[Parameter()]
[ValidateNotNullOrEmpty()]
[string[]]$ComputerName = $Env:COMPUTERNAME
)
try {
#region Defie all of the events to indicate session start or top
$sessionEvents = #(
#{ 'Label' = 'Logon'; 'EventType' = 'SessionStart'; 'LogName' = 'Security'; 'ID' = 4624 } ## Advanced Audit Policy --> Audit Logon
#{ 'Label' = 'Logoff'; 'EventType' = 'SessionStop'; 'LogName' = 'Security'; 'ID' = 4647 } ## Advanced Audit Policy --> Audit Logoff
#{ 'Label' = 'Startup'; 'EventType' = 'SessionStop'; 'LogName' = 'System'; 'ID' = 6005 }
#{ 'Label' = 'RdpSessionReconnect'; 'EventType' = 'SessionStart'; 'LogName' = 'Security'; 'ID' = 4778 } ## Advanced Audit Policy --> Audit Other Logon/Logoff Events
#{ 'Label' = 'RdpSessionDisconnect'; 'EventType' = 'SessionStop'; 'LogName' = 'Security'; 'ID' = 4779 } ## Advanced Audit Policy --> Audit Other Logon/Logoff Events
#{ 'Label' = 'Locked'; 'EventType' = 'SessionStop'; 'LogName' = 'Security'; 'ID' = 4800 } ## Advanced Audit Policy --> Audit Other Logon/Logoff Events
#{ 'Label' = 'Unlocked'; 'EventType' = 'SessionStart'; 'LogName' = 'Security'; 'ID' = 4801 } ## Advanced Audit Policy --> Audit Other Logon/Logoff Events
)
## All of the IDs that designate when user activity starts
$sessionStartIds = ($sessionEvents | where { $_.EventType -eq 'SessionStart' }).ID
## All of the IDs that designate when user activity stops
$sessionStopIds = ($sessionEvents | where { $_.EventType -eq 'SessionStop' }).ID
#endregion
## Define all of the log names we'll be querying
$logNames = ($sessionEvents.LogName | select -Unique)
## Grab all of the interesting IDs we'll be looking for
$ids = $sessionEvents.Id
## Build the insane XPath query for the security event log in order to query events as fast as possible
$logonXPath = "Event[System[EventID=4624]] and Event[EventData[Data[#Name='TargetDomainName'] != 'Window Manager']] and Event[EventData[Data[#Name='TargetDomainName'] != 'NT AUTHORITY']] and (Event[EventData[Data[#Name='LogonType'] = '2']] or Event[EventData[Data[#Name='LogonType'] = '11']])"
$otherXpath = 'Event[System[({0})]]' -f "EventID=$((#($ids).where({ $_ -ne '4624' })) -join ' or EventID=')"
$xPath = '({0}) or ({1})' -f $logonXPath, $otherXpath
foreach ($computer in $ComputerName) {
## Query each computer's event logs using the Xpath filter
if (-not ($events = Get-WinEvent -ComputerName $computer -LogName $logNames -FilterXPath $xPath)) {
Write-Warning -Message 'No logon events found'.
} else {
Write-Verbose -Message "Found [$($events.Count)] events to look through"
## Set up the output object
$output = [ordered]#{
'ComputerName' = $computer
'Username' = $null
'StartTime' = $null
'StartAction' = $null
'StopTime' = $null
'StopAction' = $null
'Session Active (Days)' = $null
'Session Active (Min)' = $null
}
## Need current users because if no stop time, they're still probably logged in
$getGimInstanceParams = #{
ClassName = 'Win32_ComputerSystem'
}
if ($computer -ne $Env:COMPUTERNAME) {
$getGimInstanceParams.ComputerName = $computer
}
$loggedInUsers = Get-CimInstance #getGimInstanceParams | Select-Object -ExpandProperty UserName | foreach { $_.split('\')[1] }
## Find all user start activity events and begin parsing
#($events).where({ $_.Id -in $sessionStartIds }).foreach({
try {
$logonEvtId = $_.Id
$output.StartAction = #($sessionEvents).where({ $_.ID -eq $logonEvtId }).Label
$xEvt = [xml]$_.ToXml()
## Figure out the login session ID
$output.Username = ($xEvt.Event.EventData.Data | where { $_.Name -eq 'TargetUserName' }).'#text'
$logonId = ($xEvt.Event.EventData.Data | where { $_.Name -eq 'TargetLogonId' }).'#text'
if (-not $logonId) {
$logonId = ($xEvt.Event.EventData.Data | where { $_.Name -eq 'LogonId' }).'#text'
}
$output.StartTime = $_.TimeCreated
Write-Verbose -Message "New session start event found: event ID [$($logonEvtId)] username [$($output.Username)] logonID [$($logonId)] time [$($output.StartTime)]"
## Try to match up the user activity end event with the start event we're processing
if (-not ($sessionEndEvent = #($Events).where({ ## If a user activity end event could not be found, assume the user is still logged on
$_.TimeCreated -gt $output.StartTime -and
$_.ID -in $sessionStopIds -and
(([xml]$_.ToXml()).Event.EventData.Data | where { $_.Name -eq 'TargetLogonId' }).'#text' -eq $logonId
})) | select -last 1) {
if ($output.UserName -in $loggedInUsers) {
$output.StopTime = Get-Date
$output.StopAction = 'Still logged in'
} else {
throw "Could not find a session end event for logon ID [$($logonId)]."
}
} else {
## Capture the user activity end time
$output.StopTime = $sessionEndEvent.TimeCreated
Write-Verbose -Message "Session stop ID is [$($sessionEndEvent.Id)]"
$output.StopAction = #($sessionEvents).where({ $_.ID -eq $sessionEndEvent.Id }).Label
}
$sessionTimespan = New-TimeSpan -Start $output.StartTime -End $output.StopTime
$output.'Session Active (Days)' = [math]::Round($sessionTimespan.TotalDays, 2)
$output.'Session Active (Min)' = [math]::Round($sessionTimespan.TotalMinutes, 2)
[pscustomobject]$output
} catch {
Write-Warning -Message $_.Exception.Message
}
})
}
}
} catch {
$PSCmdlet.ThrowTerminatingError($_)
}
First you got this error:
Attempted to perform an unauthorized
And:
There is not an event log on the BIGBERTHA computer that matches "Security"
This clearly indicates that the account used to run the query against the remote computer does not have the necesssary permission. You can't access the and/or find the Security Log because of insufficient acces rights.
In your 2nd run with the right account and elevated shell you did get further, because you now get the error:
The specified query is invalid
That means you have been able to connect to the remote computer and read the security log but get-winevent could not execute the operation because the query syntax is invalid.
This part of the code builds the filter:
$logonXPath = "Event[System[EventID=4624]] and Event[EventData[Data[#Name='TargetDomainName'] != 'Window Manager']] and Event[EventData[Data[#Name='TargetDomainName'] != 'NT AUTHORITY']] and (Event[EventData[Data[#Name='LogonType'] = '2']] or Event[EventData[Data[#Name='LogonType'] = '11']])"
$otherXpath = 'Event[System[({0})]]' -f "EventID=$((#($ids).where({ $_ -ne '4624' })) -join ' or EventID=')"
$xPath = '({0}) or ({1})' -f $logonXPath, $otherXpath
The scripts works for me... but in the end you do not need the whole functionality, think this will help:
#Query
$XPath = "Event[System[EventID=4624]] and Event[EventData[Data[#Name='TargetDomainName'] != 'Window Manager']] and Event[EventData[Data[#Name='TargetDomainName'] != 'NT AUTHORITY']] and (Event[EventData[Data[#Name='LogonType'] = '2']] or Event[EventData[Data[#Name='LogonType'] = '11']])"
#Get List containing the dnsHostNames of the computers to query
$computer = gc [path]
#Run Query against computers and gather result
$result = #(
foreach ($computer in $computers){
#run query
$events = get-winevent -LogName security -FilterXPath $XPath -ComputerName $computer
#parse events as xml and extract necessary information, return object
$eventobj = #(
foreach ($event in $events){
[xml]$xml = $event.toxml()
$attrsht = [ordered]#{
TimeCreated=$xml.event.system.TimeCreated.SystemTime
eventId=$xml.event.system.eventId
SubjectUserSid=$xml.event.EventData.data[0].'#text'
SubjectUserName=$xml.event.EventData.data[1].'#text'
SubjectDomainName=$xml.event.EventData.data[2].'#text'
TargetUserSid=$xml.event.EventData.data[4].'#text'
TargetUserName=$xml.event.EventData.data[5].'#text'
TargetDomainName=$xml.event.EventData.data[6].'#text'
LogonType=$xml.event.EventData.data[8].'#text'
LogonProcessName=$xml.event.EventData.data[9].'#text'
ipAdress=$xml.event.EventData.data[18].'#text'
}
#return event object
new-object -TypeName psobject -Property $attrsht
}
)
$attrsht = #{
Computer=$computer
Events=$eventobj
}
#return object per computer containing all events
new-object -TypeName psobject -Property $attrsht
}
)
#As the property events is an array you can export it by using json
$result | ConvertTo-Json | set-content [path]
#If you want a csv we have to flattern the array
$result = #(
foreach ($computer in $computers){
#run query
$events = get-winevent -LogName security -FilterXPath $XPath -ComputerName $computer
#parse events as xml and extract necessary information, return object
foreach ($event in $events){
[xml]$xml = $event.toxml()
$attrsht = [ordered]#{
computername=$computer
TimeCreated=$xml.event.system.TimeCreated.SystemTime
eventId=$xml.event.system.eventId
SubjectUserSid=$xml.event.EventData.data[0].'#text'
SubjectUserName=$xml.event.EventData.data[1].'#text'
SubjectDomainName=$xml.event.EventData.data[2].'#text'
TargetUserSid=$xml.event.EventData.data[4].'#text'
TargetUserName=$xml.event.EventData.data[5].'#text'
TargetDomainName=$xml.event.EventData.data[6].'#text'
LogonType=$xml.event.EventData.data[8].'#text'
LogonProcessName=$xml.event.EventData.data[9].'#text'
ipAdress=$xml.event.EventData.data[18].'#text'
}
#return event object
new-object -TypeName psobject -Property $attrsht
}
}
)
$result | export-csv [path] -NoClobber -NoTypeInformation -Delimiter ";"

File does not exist (but it's there) and Multiple ambiguous overloads found for "AddPicture" and the argument count: "2"

I'm trying to add an image to an excel worksheet with powershell 5. and VSCode.
I get these errors:
C:\CC_SnapViews\EndToEnd_view\path is correct\file.bmp
does not exist (but it's there)
Multiple ambiguous overloads found for "AddPicture" and the argument
count: "2"
When I search the internet, this error isn't coming up in the search. I was following these examples:
addPicture
addPicture github
This is my code:
$xlsx = $result | Export-Excel -Path $outFilePath -WorksheetName $errCode -Autosize -AutoFilter -FreezeTopRow -BoldTopRow -PassThru # -ClearSheet can't ClearSheet every time or it clears previous data ###left off
$ws = $xlsx.Workbook.Worksheets[$errCode]
for ($row = 2 ;( $row -le $tempRowCount ); $row++)
{
#Write-Host $($ws.Dimension.Rows)
#Write-Host $($row)
$ws.Row($row).Height
$ws.Row($row).Height = 150
$ws.Row($row)[3]
$result.GetValue($row) #$ws.Row($row)[3]
$pictureName=$result[$row].PictureID
$pictureNamePath=$result[$row].ImageFileName
#place the image in spreadsheet
#https://github.com/dfinke/ImportExcel/issues/1041 https://github.com/dfinke/ImportExcel/issues/993
$drawingName = "$($pictureName)_Col3_$($row)" #Name_ColumnIndex_RowIndex
#Write-Host $image
Write-Host $drawingName
####
if($null -ne $pictureNamePath)
{
$image = Get-Image -imageFileName $pictureNamePath ###error pictureNamePath does not exist but it does
}
else
{
Write-Host "Did not find an image file for $pictureName in $pictureNamePath"
}
$picture = $ws.Drawings.AddPicture($pictureNamePath,$image) ###error message here
}
Any ideas why powershell thinks the image file doesn't exist?
Update:
I added some debug in the foreach for the rows:
for ($row = 2 ;( $row -le $tempRowCount ); $row++)
{
#Write-Host $($ws.Dimension.Rows)
#Write-Host $($row)
$ws.Row($row).Height
$ws.Row($row).Height = 150
$ws.Row($row)[3]
$result.GetValue($row) #prints entire row info
$pictureName=$result[$row].PictureID
$pictureNamePath=$result[$row].ImageFileName
if(Test-Path $pictureNamePath)
{
Write-Host "$($pictureNamePath) exists" ##prints ...filenamepath... exists (looks good)
}
Write-Host "pic path = $pictureNamePath" ##prints pic path = ..file name path... (looks good)
...
Update2:
Adding the Get-Image function:
Function Get-Image{
[cmdletbinding()]
Param ([string]$imageFileName)
Process
{
#find image file name to look for
if($imageFileName.Exists) #if($imageFile2.Exists)
{
[System.Drawing.Image] $image = [System.Drawing.Image]::FromFile($imageFileName) #may not need this step
#need to figure out which is correct if there's multiple images
return $image
}
else {
Write-Host "$($imageFileName) does not exist"
return $null
}
} #end Process
}# End of Function
I changed my function to use Test-Path instead and it sets the image now.
Function Get-Image{
[cmdletbinding()]
Param ([string]$imageFileName)
Process
{
#find image file name to look for
if(Test-Path $imageFileName) ###instead of Exists
{
[System.Drawing.Image] $image = [System.Drawing.Image]::FromFile($imageFileName) #may not need this step
#need to figure out which is correct if there's multiple images
return $image
}
else {
Write-Host "$($imageFileName) does not exist"
return $null
}
} #end Process
}# End of Function

PowerShell Scipt for adding new Credentials

I'm trying to make script to automaticly assign credidentials based on the group that was chose. I'm getting a lot of syntax errors. Can you help?
Function Add-OSCCredential
{
$target = Read-Host "Group number"
If($target)
{
If($target -eq 1)
{[string]$result = cmdkey /add:Group1 /user:Group1 /pass:Pass1}
[ElseIf($target -eq 2)
{[string]$result = cmdkey /add:Group2 /user:Group2 /pass:Pass2}]
{
[ElseIf($target -eq 3)
{[string]$result = cmdkey /add:Group3 /user:Group3 /pass:Pass3}]
{
If($result -match "The command line parameters are incorrect")
{Write-Error "Failed to add Windows Credential to Windows vault."}
ElseIf($result -match "CMDKEY: Credential added successfully")
{Write-Host "Credential added successfully."}
}
Else
{
Write-Error "Internet(network address) or username can not be empty,please try again."
Add-OSCCredential
}
}
Add-OSCCredential
I'd suggest you use a proper editor such as vscode which will give you lots of hints concerning bad syntax.
In your case there are a lot of [] and {} parenthesis that do not make sense.
Only considering the syntax of that function, the following should 'work':
Function Add-OSCCredential {
$target = Read-Host "Group number"
If ($target) {
If ($target -eq 1) {
[string]$result = cmdkey /add:Group1 /user:Group1 /pass:Pass1
}
ElseIf ($target -eq 2) {
[string]$result = cmdkey /add:Group2 /user:Group2 /pass:Pass2
}
ElseIf ($target -eq 3) {
[string]$result = cmdkey /add:Group3 /user:Group3 /pass:Pass3
}
If ($result -match "The command line parameters are incorrect") {
Write-Error "Failed to add Windows Credential to Windows vault."
}
ElseIf ($result -match "CMDKEY: Credential added successfully") {
Write-Host "Credential added successfully."
}
}
Else {
Write-Error "Internet(network address) or username can not be empty,please try again."
Add-OSCCredential
}
}
edit:
you'd most likely want to look into a ready-to-use PowerShell Module such as CredentialManager, this way you wouldn't have to fiddle with cmdkey.exe yourself.
The returned value for Read-Host is always a string, but you treat it like an integer in your tests.
For better readability, I suggest using a switch rather that yet another set of if..elseif..else statements.
Something like this:
function Add-OSCCredential {
$target = Read-Host "Enter Group number (1-3)"
if ($target -match '1|2|3') {
switch ([int]$target) {
1 {[string]$result = cmdkey /add:Group1 /user:Group1 /pass:Pass1}
2 {[string]$result = cmdkey /add:Group2 /user:Group2 /pass:Pass2}
3 {[string]$result = cmdkey /add:Group3 /user:Group3 /pass:Pass3}
}
if($result -match "The command line parameters are incorrect") {
Write-Error "Failed to add Windows Credential to Windows vault."
}
elseif ($result -match "Credential added successfully") {
Write-Host "Credential added successfully."
}
else {
Write-Warning $result
}
}
else {
Write-Warning "Group number must be either 1, 2 or 3. Please try again."
Add-OSCCredential
}
}
Add-OSCCredential

why is no data being returned in my PowerShell script

add-type -AssemblyName System.Data.OracleClient
$username = "SYSTEM"
$password = "password"
$data_source = "production"
$connection_string = "User Id=$username;Password=$password;Data Source=$data_source"
try{
$statement = "SELECT SYSDATE FROM DUAL"
$con = New-Object System.Data.OracleClient.OracleConnection($connection_string)
$con.Open()
$cmd = $con.CreateCommand()
$cmd.CommandText = $statement
$result = $cmd.ExecuteReader()
# Do something with the results...
Write-Host $result + "data"
If($result.HasRows) {
try {
while ($result.Read())
{
"[0] : " + $result.GetValue(0)
}
}
catch
{
#log error
}
finally
{
$con.Close()
}
}
} catch {
Write-Error (“Database Exception: {0}`n{1}” -f `
$con.ConnectionString, $_.Exception.ToString())
} finally{
if ($con.State -eq ‘Open’) { $con.close() }
}
I am executing SELECT SYSDATE FROM DUAL
I am expecting 21-MAY-19
However no data is returned. (no error is presented either)
As mentioned in the above comments, you've to send the content of $result to PowerShells output stream. The output stream is used to realize the pipeline feature of Powershell. If you wrap your code in e.g. "myCode.ps1" and invoke it via:
.\myCode.ps1
The content of $result is pushed in the output stream (pipeline). Since no other cmdlet is attached to the call of myCode.ps1 the Powershell host (= your command line) will receive the content. The default behavior of the host is to dump the content.
So add the following to your code:
$result = $cmd.ExecuteReader()
# Return $result to the pipeline
$result
Read more about pipelines here and more about streams here.
UPDATE1: This link describes more or less the code sample of the question. Maybe the Orcale .NET data provider is missing. Add it via:
Add-Type -Path "PathToDll\Oracle.ManagedDataAccess.dll"
Hope that helps.

Retrieve the Windows Identity of the AppPool running a WCF Service

I need to verify that the underlying server-side account running my WCF Service has correct ACL permissions to various points on the local file system. If I can get the underlying Windows Identity, I can take it from there. This folds into a larger Powershell script used after deployment.
Below is my powershell snippet, that get the ApplicationPoolSid, how do you map this to the AppPool's Windows Identity?
$mywcfsrv = Get-Item IIS:\AppPools\<MyWCFServiceName>;
Updated below to include Keith's snippet
For completeness, here's the solution:
Function Get-WebAppPoolAccount
{
param ( [Parameter(Mandatory = $true, Position = 0)]
[string]
$AppPoolName )
# Make sure WebAdmin module is loaded.
$module = (Get-Module -ListAvailable) | ForEach-Object { if ($_.Name -like 'WebAdministration') { $_ } };
if ($module -eq $null)
{
throw "WebAdministration PSSnapin module is not available. This module is required in order to interact with WCF Services.";
}
Import-Module $module;
# Get the service account.
try
{
$mywcfsrv = Get-Item (Join-Path "IIS:\AppPools" $AppPoolName);
}
catch [System.Exception]
{
throw "Unable to locate $AppPoolName in IIS. Verify it is installed and running.";
}
$accountType = $mywcfsrv.processModel.identityType;
$account = $null;
if ($accountType -eq 'LocalSystem')
{
$account = 'NT AUTHORITY\SYSTEM';
}
elseif ($accountType -eq 'LocalService')
{
$account = 'NT AUTHORITY\LOCAL SERVICE';
}
elseif ($accountType -eq 'NetworkService')
{
$account = 'NT AUTHORITY\NETWORK SERVICE';
}
elseif ($accountType -eq 'SpecificUser')
{
$account = $mywcfsrv.processModel.userName;
}
return $account;
}
Like so:
$mywcfsrv = Get-Item IIS:\AppPools\<MyWCFServiceName>
$mywcfsrv.processModel.identityType

Resources