Connecting to azure service fabric fails with 0x800b0109 - azure-service-fabric

I have set up a new Service Fabric instance and I can successfully connect to the Service Fabric Explorer to view the current state of the service. I would now like to connect to the Service Fabric instance using powershell:
Connect-ServiceFabricCluster -ConnectionEndpoint <path>:19000 -KeepAliveIntervalInSec 10 -X509Credential -ServerCertThumbprint <PrimaryCertificateThumbprint> -FindType FindByThumbprint -FindValue <Admin Client certificate thumbprint installed locally> -StoreLocation CurrentUser -StoreName My
Whenever I run this command I get the error:
Connect-ServiceFabricCluster : FABRIC_E_SERVER_AUTHENTICATION_FAILED: 0x800b0109
Can anyone tell me what is causing this error and how I fix it?

The documentation is somewhat different from your command:
PS C:\> $ConnectArgs = #{ ConnectionEndpoint = 'mycluster.cloudapp.net:19000'; X509Credential = $True; StoreLocation = 'CurrentUser'; StoreName = "MY"; ServerCommonName = "mycluster.cloudapp.net"; FindType = 'FindByThumbprint'; FindValue = "AA11BB22CC33DD44EE55FF66AA77BB88CC99DD00" }
PS C:\> Connect-ServiceFabricCluster $ConnectArgs

Related

Powershell Invoke-Command remote works manually, but not from Jenkins

I have a really strange situation where the same command works when run manually from a Windows Server 2012 R2, but not from the Jenkins slave process running on the same server.
First, the output from the manual run, an admin PowerShell window:
PS C:\Users\Administrator> whoami
win-cm8utd1qfnc\administrator
PS C:\Users\Administrator> Invoke-Command -computername web.sandbox.MUNGED.com -scriptblock {iisreset /restart}
Attempting stop...
Internet services successfully stopped
Attempting start...
Internet services successfully restarted
Great. Now, the relevant snippet of Jenkins pipeline code:
pipeline {
stages {
stage('Deploy web') {
agent { label 'windows-server-2012' }
environment {
SERVER = 'web.sandbox.MUNGED.com'
}
steps {
powershell """
whoami
Invoke-Command -computername ${SERVER} -scriptblock {iisreset /restart}
"""
}
}
}
}
And the output when running from Jenkins:
07:37:29 win-cm8utd1qfnc\administrator
07:37:29 [web.sandbox.MUNGED.com] Connecting to remote server web.sandbox.MUNGED.com failed with the following error message : Access is denied. For more information, see the
07:37:29 about_Remote_Troubleshooting Help topic.
07:37:29 + CategoryInfo : OpenError: (web.sandbox.MUNGED.com:String) [], PSRemotingTransportException
07:37:29 + FullyQualifiedErrorId : AccessDenied,PSSessionStateBroken
The Windows servers (Jenkins slave and web server) are not part of a domain, but have the same Administrator password, which seems to make the authentication work well.
For what it's worth, here's the winrm configuration for the Jenkins slave:
PS C:\Users\Administrator> winrm get winrm/config
Config
MaxEnvelopeSizekb = 500
MaxTimeoutms = 1800000
MaxBatchItems = 32000
MaxProviderRequests = 4294967295
Client
NetworkDelayms = 5000
URLPrefix = wsman
AllowUnencrypted = false
Auth
Basic = true
Digest = true
Kerberos = true
Negotiate = true
Certificate = true
CredSSP = false
DefaultPorts
HTTP = 5985
HTTPS = 5986
TrustedHosts = *
Service
RootSDDL = O:NSG:BAD:P(A;;GA;;;BA)(A;;GR;;;IU)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)
MaxConcurrentOperations = 4294967295
MaxConcurrentOperationsPerUser = 1500
EnumerationTimeoutms = 240000
MaxConnections = 300
MaxPacketRetrievalTimeSeconds = 120
AllowUnencrypted = true
Auth
Basic = true
Kerberos = true
Negotiate = true
Certificate = false
CredSSP = false
CbtHardeningLevel = Relaxed
DefaultPorts
HTTP = 5985
HTTPS = 5986
IPv4Filter = *
IPv6Filter = *
EnableCompatibilityHttpListener = false
EnableCompatibilityHttpsListener = false
CertificateThumbprint
AllowRemoteAccess = true
Winrs
AllowRemoteShellAccess = true
IdleTimeout = 7200000
MaxConcurrentUsers = 10
MaxShellRunTime = 2147483647
MaxProcessesPerShell = 4096
MaxMemoryPerShellMB = 8192
MaxShellsPerUser = 30
And from the webserver:
PS C:\Users\Administrator> winrm get winrm/config
Config
MaxEnvelopeSizekb = 500
MaxTimeoutms = 1800000
MaxBatchItems = 32000
MaxProviderRequests = 4294967295
Client
NetworkDelayms = 5000
URLPrefix = wsman
AllowUnencrypted = false
Auth
Basic = true
Digest = true
Kerberos = true
Negotiate = true
Certificate = true
CredSSP = false
DefaultPorts
HTTP = 5985
HTTPS = 5986
TrustedHosts = *
Service
RootSDDL = O:NSG:BAD:P(A;;GA;;;BA)(A;;GR;;;IU)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)
MaxConcurrentOperations = 4294967295
MaxConcurrentOperationsPerUser = 1500
EnumerationTimeoutms = 240000
MaxConnections = 300
MaxPacketRetrievalTimeSeconds = 120
AllowUnencrypted = true
Auth
Basic = true
Kerberos = true
Negotiate = true
Certificate = false
CredSSP = false
CbtHardeningLevel = Relaxed
DefaultPorts
HTTP = 5985
HTTPS = 5986
IPv4Filter = *
IPv6Filter = *
EnableCompatibilityHttpListener = false
EnableCompatibilityHttpsListener = false
CertificateThumbprint
AllowRemoteAccess = true
Winrs
AllowRemoteShellAccess = true
IdleTimeout = 7200000
MaxConcurrentUsers = 10
MaxShellRunTime = 2147483647
MaxProcessesPerShell = 25
MaxMemoryPerShellMB = 1024
MaxShellsPerUser = 30
EDIT: I got it to work after a fashion. Firstly, on the Jenkins slave, I had to run:
winrm set winrm/config/client '#{AllowUnencrypted="true"}'
Then I changed the pipeline to:
powershell """
\$creds = Import-CliXml \$home\\creds.xml
Invoke-Command -computername ${SERVER} -scriptblock {iisreset /restart} -Authentication Basic -Credential \$creds
"""
where creds.xml was a file previously generated with Get-Credentials | Export-CliXml creds.xml.
That still doesn't explain why the behaviour is different between manual PowerShell and Jenkins slave. It's a bit of an annoying workaround, but at least I can proceed.
You are probably hitting the remote execution script limitation from Jenkins (security is the cause here). You need to configure the Jenkins server to be able to run the script "normally" but you will always have to add the credentials.
The script you are running from powershell command line uses the default credentials for your win-cm8utd1qfnc\administrator so the following will work as you wrote:
PS C:\Users\Administrator> whoami
win-cm8utd1qfnc\administrator
PS C:\Users\Administrator> Invoke-Command -computername web.sandbox.MUNGED.com -scriptblock {iisreset /restart}
Attempting stop...
Internet services successfully stopped
Attempting start...
Internet services successfully restarted
However, when running Powershell from Jenkins, a plugin by its nature, you are hitting the security-by-design limitation. You don't want to run "wild" scripts with your Administration account.
The most reasonable guide I have found on this topic was here (the following is excerpt from the page:
Executing Powershell scripts/commands remotely
he above job creates a text file on the Jenkins server itself. To
setup remote Powershell scripts we first need to configure Jenkins
server for remote Powershell script execution. To enable remote
Windows machine in to the WS-Man trusted list on Jenkins servers.
Execute the below command on Powershell window on Jenkins server. The
command will add all the remote machine to the trusted list.
Set-Item WSMan:\localhost\Client\TrustedHosts *
Along with the commands, we would also need to enable remote script
execution also. To enable execution of Powershell scripts remotely
execute the following command in Powershell window on Jenkins server.
Set-ExecutionPolicy RemoteSigned –Force
We will have to install a new plugin named EnvInject Plugin for
transferring variables e.g. passwords.
Login to Jenkins and navigate to Manage Jenkins > Manage Plugins
Click on the Available tab and Enter EnvInject in the filter box
Select the plugin showing by name PowerShell Plugin
Select Download now and install after restart
Creating a job to restart Windows time service:
On Jenkins interface, click New Item
Enter Remote Powershell scripts for the job name. Select Freestyle project
Tick This build is parameterized. Create following parameters
Type: String Parameter
Name: ServerIp/Hostname
Description: Remote machine’s IP address.
Type: String Parameter
Name: UserName
Type: Password Parameter
Name: Password
Now, Click Add Parameter list and select the Choice Parameter. Enter the options on new lines inside the Choices text box. Also,
provide description for the options mentioned:
The following script is based on the above link, but I did not like the plain text used so I have decided to rewrite it to use Powershell's SecureString
First to store your admin password:
read-host -AsSecureString | ConvertFrom-SecureString | Out-File C:\<your_path>\securestring.txt
Then have the script:
# Configure build failure on errors on the remote machine similar to set -x on bash script
$ErrorActionPreference = 'Stop'
# Create a PSCredential Object using the "Username" and "Password" variables created on job
$password = Get-Content 'C:\<your_path>\securestring.txt' | ConvertTo-SecureString
$creddentials = New-Object System.Management.Automation.PSCredential -ArgumentList $env:UserName, $password
# It depends on the type of job you are executing on the remote machine as to if you want to use "-ErrorAction Stop" on your Invoke-Command.
Invoke-Command -ComputerName $env:Computer -Credential $credentials -ScriptBlock { Restart-Service -Name W32Time }
See this question: Remote Access with Powershell and Jenkins
Need to change service user from Local System to administrator.

Deploy Service Fabric from powershell. Error -> Get-ServiceFabricClusterManifest : Cluster connection instance is null

I am trying to publish Service Fabric application to Azure with powershell. I want to connect to the cluster and then call script "Deploy-FabricApplication.ps1"(one that is generated when new project is created in visual studio)
To do that I have created new script file which is responsible for connecting with cluster and then from that same script file I am calling "Deploy-FabricApplication.ps1".
After launching my script I am getting following error:
Get-ServiceFabricClusterManifest : Cluster connection instance is null
At C:\Program Files\Microsoft SDKs\Service Fabric\Tools\PSModule\ServiceFabricSDK\Publish-UpgradedServiceFabricApplication.ps1:116 char:28
+ $clusterManifestText = Get-ServiceFabricClusterManifest
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ResourceUnavailable: (:) [Get-ServiceFabricClusterManifest], NullReferenceException
+ FullyQualifiedErrorId : GetClusterConnectionErrorId,Microsoft.ServiceFabric.Powershell.GetClusterManifest
In connection script and Deploy-FabricApplication.ps1 I am calling "Test-ServiceFabricClusterConnection" and in both scripts it returns True also in both scripts I am calling "Get-ServiceFabricClusterManifest" and in both cases it returns to me manifest but when I have added "Test-ServiceFabricClusterConnection" to "Publish-UpgradedServiceFabricApplication.ps1" then it has returned that same error as mentioned befor but for "Test-ServiceFabricClusterConnection" call.
Code for connecting script:
Param
(
[String]
$PublishProfileFile,
[String]
$ApplicationPackagePath,
[Switch]
$DeployOnly,
[Boolean]
$UnregisterUnusedApplicationVersionsAfterUpgrade,
[String]
[ValidateSet('None', 'ForceUpgrade', 'VetoUpgrade')]
$OverrideUpgradeBehavior = 'None',
[String]
[ValidateSet('Never','Always','SameAppTypeAndVersion')]
$OverwriteBehavior = 'Never',
[Switch]
$SkipPackageValidation,
[String]
$ConnectionEndpoint,
[String]
$ServerCertThumbprint,
[String]
$FindType,
[String]
$FindValue,
[String]
$StoreLocation,
[String]
$StoreName
)
$connectArgs = #{ ConnectionEndpoint = $ConnectionEndpoint; X509Credential = $True; StoreLocation = $StoreLocation; StoreName = $StoreName; ServerCertThumbprint = $ServerCertThumbprint; FindType = $FindType; FindValue = $FindValue }
try
{
Connect-ServiceFabricCluster #connectArgs;
$connection = Get-ServiceFabricClusterConnection;
Write-Host $connection;
$m = Get-ServiceFabricClusterManifest
Write-Host $m;
}
catch [System.Fabric.FabricObjectClosedException]
{
Write-Warning "Service Fabric cluster may not be connected."
throw
}
.\Deploy-FabricApplication.ps1 -PublishProfileFile $PublishProfileFile -ApplicationPackagePath $ApplicationPackagePath -OverrideUpgradeBehavior $OverrideUpgradeBehavior -OverwriteBehavior $OverwriteBehavior -DeployOnly:$DeployOnly -UnregisterUnusedApplicationVersionsAfterUpgrade:$UnregisterUnusedApplicationVersionsAfterUpgrade -UseExistingClusterConnection:$true -SkipPackageValidation:$SkipPackageValidation
To summarize, I have no idea how to establish connection to cluster and then use it in Deploy-FabricApplication.ps1
Thanks for help
When calling Connect-ServiceFabricCluster a local $clusterConnection variable is set. Some of the SDK scripts then expect that variable to be set, but because you're executing your script in different scope, that local variable isn't available to them.
You can either dot source the call to Deploy-FabricApplication.ps1
. .\Deploy-FabricApplication.ps1 -PublishProfileFile $PublishProfileFile -ApplicationPackagePath $ApplicationPackagePath -OverrideUpgradeBehavior $OverrideUpgradeBehavior -OverwriteBehavior $OverwriteBehavior -DeployOnly:$DeployOnly -UnregisterUnusedApplicationVersionsAfterUpgrade:$UnregisterUnusedApplicationVersionsAfterUpgrade -UseExistingClusterConnection:$true -SkipPackageValidation:$SkipPackageValidation
or create a $global:clusterConnection variable that contains the local $clusterConnection variable
$global:clusterConnection = $clusterConnection

PowerShell DSC Invalid MOF definition for node 'localhost'

As I'm new to PowerShell and also DSC (and programming in total) i have a question to which i couldn't find an answer in the web.
I'm trying to install an msi (or an exe) with PS DSC. I sucessfully wrote a script to check and install windows-features and to install JDK and set the ressources.
But with my next step I seem to be overchallenged.
so heres my code so far:
$ConfigurationData = #{
AllNodes = #(
#{
NodeName="*"
PSDscAllowPlainTextPassword=$true
}
)
}
Configuration AppFabric
{
param (
$TargetNodes,
[Parameter(Mandatory=$false)]
[PSCredential]$Credential
)
Import-DscResource –ModuleName ’PSDesiredStateConfiguration’
Node localhost
{
Package AppFabric
{
Ensure = "Present"
Name = "AppFabric"
Path = "$PWD\src\AppFabric\package\appfabric-1.1-for-windows-server-64.msi"
ProductId = ""
LogPath = "$PWD\logs\$env:computername-AppFabric"
Arguments = "/i HostingServices,CacheClient,HostingServicesAdmin"
Credential = "$Credential"
}
}
}
AppFabric -OutputPath $PWD\mof\AppFabric\
Start-DscConfiguration -Path $PWD\mof\AppFabric\ -wait -verbose -Force
So as you see i'm trying to install AppFabric on a Windows Server 2012R2 up to date.
When i Run the script i get following error:
I have no clue, what that means and can't find anything on the web that could help.
If you need further information, let me know, as I said, I'm new to this :x
Thanks!
Edit:
If I try to do it without credentials I get the following:
VERBOSE: Perform operation 'Invoke CimMethod' with following parameters, ''methodName' = SendConfigurationApply,'className' = MSFT_DSCLocalConfigurationManager,'namespaceName' = root/Microsoft/Windows/DesiredStateConfiguration'.
You are treating the Credential property as a string instead of PSCredential.
Remove double quotes from Credential property to fix the issue.
Package AppFabric
{
Ensure = "Present"
Name = "AppFabric"
Path = "$PWD\src\AppFabric\package\appfabric-1.1-for-windows-server-64.msi"
ProductId = ""
LogPath = "$PWD\logs\$env:computername-AppFabric"
Arguments = "/i HostingServices,CacheClient,HostingServicesAdmin"
Credential = $Credential
}

PowerShell DSC Pull Server returns HTTP 503 Service Unavailable

I'm using the PowerShell 5.0 September Preview to configure a PowerShell Desired State Configuration Pull Server on a Windows Server 2012 R2 virtual machine running on VMware Workstation. To perform the configuration of the DSC Pull Server, I am using a code snippet that I pulled off of the Microsoft PowerShell MSDN blog, which leverages the xPSDesiredStateConfiguration module's xDscWebService DSC resource.
When I attempt to test the OData endpoint for the DSC Pull Server, I receive a HTTP 503: Service Unavailable message. Any ideas on how to debug and fix this?
configuration DscWebService
{
param
(
[ValidateNotNullOrEmpty()]
[string] $CertificateThumbPrint = 'AllowUnencryptedTraffic'
)
Import-DSCResource -ModuleName xPSDesiredStateConfiguration;
WindowsFeature DSCServiceFeature
{
Ensure = 'Present';
Name = 'DSC-Service';
}
WindowsFeature WinAuth
{
Ensure = 'Present';
Name = 'web-Windows-Auth';
}
xDscWebService PSDSCPullServer
{
Ensure = 'Present';
EndpointName = 'PullSvc';
Port = 10100;
PhysicalPath = "$env:SystemDrive\inetpub\wwwroot\PSDSCPullServer";
CertificateThumbPrint = $CertificateThumbPrint;
ModulePath = "$env:PROGRAMFILES\WindowsPowerShell\DscService\Modules";
ConfigurationPath = "$env:PROGRAMFILES\WindowsPowerShell\DscService\Configuration";
State = 'Started';
DependsOn = '[WindowsFeature]DSCServiceFeature';
}
xDscWebService PSDSCConformanceService
{
Ensure = 'Present';
EndpointName = 'DscConformance';
Port = 10101;
PhysicalPath = "$env:SystemDrive\inetpub\wwwroot\PSDSCComplianceServer";
CertificateThumbPrint = 'AllowUnencryptedTraffic';
State = 'Started';
IsComplianceServer = $true;
DependsOn = #('[WindowsFeature]DSCServiceFeature', '[WindowsFeature]WinAuth','[xDSCWebService]PSDSCPullServer') ;
}
}
DscWebService -ComputerName dsc01.t.loc -OutputPath c:\dsc\PullServer -CertificateThumbPrint 00A2F55847C5523FE6CB0C2EE132C638339EA3A8;
Start-DscConfiguration -Wait -Verbose -Path c:\dsc\PullServer -Force;
a 503 Error usually indicates an issue with the apppool associated with a site. Run the following to see the state of your apppools
Get-ChildItem IIS:\AppPools

Powershell installing/uninstalling windows services on a remote machine

I am using powershell 1.0 and I need to install a service on a remote machine and first uninstall it if it exists.
This is my script I have that installs the service, however, I seem unable to uninstall the
service. I have tried installutil however the service path is a network path which installutil, throws errors over.
I'm sure there must be a better and cleaner way of approaching this.
$class = "Win32_Service"
$method = "Create"
$mc = [wmiclass]"\\DUMMYServer\ROOT\CIMV2:$class"
$inparams = $mc.PSBase.GetMethodParameters($method)
$inparams.DesktopInteract = $false
$inparams.DisplayName = "DummyService"
$inparams.ErrorControl = 0
$inparams.LoadOrderGroup = $null
$inparams.LoadOrderGroupDependencies = $null
$inparams.Name = "DummyMessageService"
$inparams.PathName = '\\DummyServer\c$\Applications\DummyMessageWindowsService\DummyWindowsService.exe'
$inparams.ServiceDependencies = $null
$inparams.ServiceType = 16
$inparams.StartMode = "Automatic"
$inparams.StartName = $null # will start as localsystem builtin if null
$inparams.StartPassword = $null
$result = $mc.PSBase.InvokeMethod($method,$inparams,$null)
$result | Format-List
If you're stuck on PowerShell 1.0, check out psexec which will allow you to run installutil.exe on the remote machine. If you were on PowerShell 2.0 on both the local and remote machines, you could use remoting to run installutil.exe on the remote machine.