Author Posts

March 20, 2016 at 4:56 pm

I am trying to write a script that user can run and give his credentials and logoff disconnected citrix session, I can able to write some code and it is working if I am in the same domain as the citrix server, if I connect to citrix server from other pcs and try to run this script, it is failing to connect to the mentioned domain, need help in this issue, to give context, here is the code:

# Import the Active Directory module for the Get-ADComputer CmdLet
Import-Module ActiveDirectory

Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.DirectoryServices.AccountManagement

#Form to take username and password
$objForm = New-Object System.Windows.Forms.Form
$objForm.Text = "Citrix User Session Disconnection"
$objForm.Size = New-Object System.Drawing.Size(300,200)
$objForm.StartPosition = "CenterScreen"

#Data Label
$Label = New-Object System.Windows.Forms.Label
$Label.Location = New-Object System.Drawing.Size(10,130)
$Label.Size = New-Object System.Drawing.Size(250,150)
$Label.ForeColor = "White"
$Label.BackColor = "Blue"
$Label.Text = "***Give your Citrix username and password to logoff the user from the server.***"
$objForm.Controls.Add($Label)

#Username Label
$userLabel = New-Object System.Windows.Forms.Label
$userLabel.Location = New-Object System.Drawing.Size(10,20)
$userLabel.Size = New-Object System.Drawing.Size(80,30)
$userLabel.Text = "User Name"
$objForm.Controls.Add($userLabel)

#Username Textbox
$userTextBox = New-Object System.Windows.Forms.TextBox
$userTextBox.Location = New-Object System.Drawing.Size(130,20)
$userTextBox.Size = New-Object System.Drawing.Size(150,20)
$objForm.Controls.Add($userTextBox)

#Password Label
$PassLabel = New-Object System.Windows.Forms.Label
$PassLabel.Location = New-Object System.Drawing.Size(10,60)
$PassLabel.Size = New-Object System.Drawing.Size(80,30)
$PassLabel.Text = "Password"
$objForm.Controls.Add($PassLabel)

#Password Textbox
$PassTextBox2 = New-Object System.Windows.Forms.MaskedTextBox
$PassTextBox2.PasswordChar = '*'
$PassTextBox2.Location = New-Object System.Drawing.Size(130,60)
$PassTextBox2.Size = New-Object System.Drawing.Size(150,20)
$objForm.Controls.Add($PassTextBox2)

#Disconnect Button
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(200,100)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.ForeColor = "Red"
$OKButton.Text = "Disconnect"
$OKButton.Add_Click({$username=$userTextBox.Text;$objForm.Close()})
$OKButton.Add_Click({$Password=$PassTextBox2.Text;$objForm.Close()})
$objForm.Controls.Add($OKButton)

$objForm.ShowDialog()

Read-Host "DOMAIN\USERNAME" -AsSecureString | ConvertFrom-SecureString | Out-File C:\SecureData\SecureString.txt
#SharePoint Admin Account
$SPAdmin = "DOMAIN\ADMIN"
$Password = Get-Content C:\SecureDate\securestring.txt | convertto-securestring
$Credential = new-object -typename System.Management.Automation.PSCredential -argumentlist $SPAdmin, $Password

Get-WmiObject -Class Win32_Service -ComputerName "Server" -Filter "Name='ServiceName'" -Credential $Credential

#Authenticaton
$Domain = $env:USERDOMAIN
$ct = [System.DirectoryServices.AccountManagement.ContextType]::Domain
$pc = New-Object System.DirectoryServices.AccountManagement.PrincipalContext $ct,$Domain
$auth = $pc.ValidateCredentials($userName,$Password)

# Get today's date for the report
$today = Get-Date

# Create a fresh variable to collect the results. You can use this to output as desired
$SessionList = "ACTIVE SERVER SESSIONS REPORT – " + $today + "`n`n"

# Query Active Directory for computers running a Server operating system
#$Servers = Get-ADComputer -Filter {OperatingSystem -like "*server*"}
$Servers = Import-Csv C:\powershell\Test.csv

if ($auth -eq "True")
{
# Loop through the list to query each server for login sessions
ForEach ($Server in $Servers) {
$ServerName = $Server.Name

# When running interactively, uncomment the Write-Host line below to show which server is being queried
# Write-Host "Querying $ServerName"

# Run the qwinsta.exe and parse the output
$queryResults = (qwinsta /SERVER:$ServerName | foreach { (($_.trim() -replace "\s+",","))} | ConvertFrom-Csv)

# Pull the session information from each instance
ForEach ($queryResult in $queryResults) {
$RDPUser = $queryResult.USERNAME
$sessionType = $queryResult.SESSIONNAME

# We only want to display where a "person" is logged in. Otherwise unused sessions show up as USERNAME as a number

If (($RDPUser -match $username) -and ($RDPUser -ne $NULL)) {
# When running interactively, uncomment the Write-Host line below to show the output to screen
# Write-Host $ServerName logged in by $RDPUser on $sessionType
$SessionList = $SessionList + "`n`n" + $ServerName + " logged in by " + $RDPUser + " on " + $sessionType
logoff $sessionType /server:$ServerName
Write-Host $RDPUser "LoggedOff"
}
}
}
}

else {
$Font = New-Object System.Drawing.Font("Times New Roman",14,[System.Drawing.FontStyle]::Italic)
#Form to display the error
$objForm2 = New-Object System.Windows.Forms.Form
$objForm2.Text = "Citrix User Session Disconnection"
$objForm2.Size = New-Object System.Drawing.Size(300,200)
$objForm2.StartPosition = "CenterScreen"
$objForm2.BackColor = "Yellow"

#Error message
$errorLabel = New-Object System.Windows.Forms.Label
$errorLabel.Location = New-Object System.Drawing.Size(10,20)
$errorLabel.Size = New-Object System.Drawing.Size(250,150)
$errorLabel.Text = "'Username/Password is not correct' Or 'User Not Logged in the Server'"
$errorLabel.Font = $Font
$errorLabel.forecolor = "Red"
$objForm2.Controls.Add($errorLabel)
$objForm2.ShowDialog()

}

March 27, 2016 at 7:46 am

That's just part of the way Windows works. From outside the domain, there's no shared authentication context, so the PC can't obtain a Kerberos ticket for the server. Given that you're forced to use DCOM for this, I'm not sure how you'd work around it.

March 28, 2016 at 9:20 pm

Can you please let me know, if there are any alternatives for the above code?

March 29, 2016 at 5:48 am

Not that I'm aware of. An "alternative" would necessitate changing the entire way Windows works.