Windows Server 2016 Dockerfile install service - powershell

I am attempting to install a service in a docker container on windows server2016.
Simply placing the service there and Powershelling:
New-Service -Name Bob -StartupType Automatic -BinaryPathName .\SVCHost.exe
Adds the service however in the container I get the result:
PS C:\Program Files\COMPANY\Repository> start-service -Name bob
start-service : Service 'bob (Bob)' cannot be started due to the following error: Cannot start service Bob on computer '.'.
At line:1 char:1
+ start-service -Name bob
+ ~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OpenError: (System.ServiceProcess.ServiceController:ServiceController) [Start-Service], ServiceCommandException
I have attempted creating a user and setting the startup user credentials but same issue.
Looking at https://github.com/Microsoft/sql-server-samples/blob/master/samples/manage/windows-containers/mssql-server-2016-express-windows/dockerfile shows that they use sqlexpress to do the install of the service.
Long story short...
How do I register a service in a Windows server 2016 Docker container

Also, look at the Dockerfile for microsoft/iis. The real work in the container is done in the IIS Windows Service, but the entrypoint is a binary called ServiceMonitor.exe. The monitor checks the Windows Service, if the Service fails the exe fails, so Docker knows the container is unhealthy.

Fully qualifying the install name works. thanks #Elton Stoneman
or figured out this works too in my program
public static bool Install(string serviceName, string serviceDescription, string logonUsername, string logonPassword, string exeFile)
{
string managementPath = #"\\.\ROOT\CIMV2:Win32_Service";
ManagementClass mc = new ManagementClass(managementPath);
ManagementBaseObject inParams = mc.GetMethodParameters("create");
inParams["Name"] = serviceName;
inParams["DisplayName"] = serviceDescription;
inParams["PathName"] = exeFile + " -name " + "\"" + serviceName + "\"";
inParams["ServiceType"] = ServiceType.Win32OwnProcess;
inParams["ErrorControl"] = 0;
inParams["StartMode"] = ServiceStartMode.Automatic;
inParams["DesktopInteract"] = false;
inParams["StartName"] = logonUsername;
inParams["StartPassword"] = logonPassword;
inParams["LoadOrderGroup"] = null;
inParams["LoadOrderGroupDependencies"] = null;
inParams["ServiceDependencies"] = null;
ManagementBaseObject outParams = mc.InvokeMethod("create", inParams, null);
string status = outParams["ReturnValue"].ToString();
return (status == "0" || status == "23");
}

Related

packer error Failed to send shutdown command: dial tcp 172.29.48.100:22: i/o timeout

I am trying packer builder with provisioner "shell-local". After successful OS installation I am trying to attach second network adapter. But it stuck in this error. Platform Hyper-V. Code looks like:
source "hyperv-iso" "build-debian" {
boot_command = ["<wait><wait><wait><esc><wait><wait><wait>",
"/install.amd/vmlinuz ",
"initrd=/install.amd/initrd.gz ", "auto=true ", "interface=eth0 ",
"netcfg/disable_dhcp=true ",
"netcfg/confirm_static=true ", "netcfg/get_ipaddress=172.29.48.100 ",
"netcfg/get_netmask=255.255.255.0 ",
"netcfg/get_gateway=172.29.48.1 ", "netcfg/get_nameservers=8.8.8.8 8.8.4.4 ",
"netcfg/get_domain=domain ",
"netcfg/get_hostname=hostname ", "url=http://{{ .HTTPIP }}:{{ .HTTPPort }}/preseed.cfg ",
"vga=788 noprompt quiet --<enter> "]
boot_wait = "10s"
configuration_version = "${var.hyperv_version}"
cpus = "${var.cpus}"
disk_block_size = "${var.hyperv_disk_block_size}"
disk_size = "${var.disk_size}"
memory = "${var.memory}"
generation = "${var.hyperv_generation}"
guest_additions_mode = "disable"
http_directory = "${local.http_directory}"
iso_checksum = "sha256:e307d0e583b4a8f7e5b436f8413d4707dd4242b70aea61eb08591dc0378522f3"
iso_url = "http://debian.mirror.vu.lt/debian-cd/11.5.0/amd64/iso-cd/debian-11.5.0-amd64-netinst.iso"
output_directory = "${var.build_directory}/packer-${local.template}-${var.git_sha}"
shutdown_command = "echo 'vagrant' | sudo -S /sbin/halt -h -p"
ssh_host = "${var.ip_address_eth0}"
ssh_keep_alive_interval = "-1s"
ssh_password = "vagrant"
ssh_port = 22
ssh_timeout = "120m"
ssh_username = "vagrant"
headless = "false"
switch_name = "VmNAT"
vm_name = "${local.template}-${var.git_sha}"
}
build {
name = "BUILD: Debian v11.5"
source "hyperv-iso.build-debian" {
}
provisioner "shell-local" {
execute_command = ["powershell.exe", "{{.Vars}} {{.Script}}"]
env_var_format = "$env:%s=\"%s\"; "
tempfile_extension = ".ps1"
pause_before = "60s"
inline =["Import-Module Hyper-V",
"Stop-VM -Name ${local.template}-${var.git_sha}",
"Timeout /T 20",
"Add-VMNetworkAdapter -VMName ${local.template}-${var.git_sha} -SwitchName ${var.hyperv_switch} -Name Static -DeviceNaming Off",
"Start-VM -Name ${local.template}-${var.git_sha}"
}
}
packer logs
Maybe I'm doing something wrong? And someone know how to fix ? Ty for any help
EDITED:
I made some changes and I think its problem with timeout. While provisioned VM are restarted packer after that tries reconnect to VM, but in this time VM still booting and I get errors like. Is that possible that ssh_timeout works only on first boot ?

DSC for initialising and formatting disks

I need to format a disk for servers using DSC. I tried using the below from
https://blogs.msdn.microsoft.com/timomta/2016/04/23/how-to-use-powershell-dsc-to-prepare-a-data-drive-on-an-azure-vm/#comment-1865
But it doesnt work as it doesn't seem to be complete, I get errors
"+ xWaitforDisk Disk2 + ~~~~~~~~~~~~ Resource 'xWaitForDisk' requires
that a value of type 'String' be provided for property 'DiskId'.
At line:18 char:1 + DiskNumber = 2 + ~~~~~~~~~~ The member
'DiskNumber' is not valid. Valid members are 'DependsOn', 'DiskId',
'DiskIdType', 'PsDscRunAsCredential', 'RetryCount',
'RetryIntervalSec'. "
Configuration DataDisk
{
Import-DSCResource -ModuleName xStorage
Node localhost
{
xWaitforDisk Disk2
{
DiskNumber = 2
RetryIntervalSec = 60
Count = 60
}
xDisk FVolume
{
DiskNumber = 2
DriveLetter = 'F'
FSLabel = 'Data'
}
}
You need to replace DiskNumber with DiskID.
Take a look at the examples on GitHub https://github.com/PowerShell/StorageDsc/tree/dev/Modules/StorageDsc/Examples/Resources
You can find the DiskId with powershell use the command: Get-Disk

Powershell DSC client can't register with pull server

For the past few days, I have been trying to create a development/test environment where I can automate deployments with DSC.
I have been using WMF5.1.
The pullserver has been set up using the example: Sample_xDscWebServiceRegistrationWithSecurityBestPractices
From xPSDesiredStateConfiguration 5.1.0.0.
configuration Sample_xDscWebServiceRegistrationWithSecurityBestPractices
{
param
(
[string[]]$NodeName = 'CORE-O-DSCPull.CORE.local',
[ValidateNotNullOrEmpty()]
[string] $certificateThumbPrint,
[Parameter(HelpMessage='This should be a string with enough entropy (randomness) to protect the registration of clients to the pull server. We will use new GUID by default.')]
[ValidateNotNullOrEmpty()]
[string] $RegistrationKey # A guid that clients use to initiate conversation with pull server
)
Import-DSCResource -ModuleName xPSDesiredStateConfiguration -ModuleVersion '5.1.0.0'
Node $NodeName
{
WindowsFeature DSCServiceFeature
{
Ensure = "Present"
Name = "DSC-Service"
}
xDscWebService PSDSCPullServer
{
Ensure = "Present"
EndpointName = "PSDSCPullServer"
Port = 8080
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"
RegistrationKeyPath = "$env:PROGRAMFILES\WindowsPowerShell\DscService"
AcceptSelfSignedCertificates = $true
UseSecurityBestPractices = $true
}
File RegistrationKeyFile
{
Ensure = 'Present'
Type = 'File'
DestinationPath = "$env:ProgramFiles\WindowsPowerShell\DscService\RegistrationKeys.txt"
Contents = $RegistrationKey
}
}
}
I apply the MOF file to my pull server without issues. I create a meta MOF using the same example:
[DSCLocalConfigurationManager()]
configuration Sample_MetaConfigurationToRegisterWithSecurePullServer
{
param
(
[ValidateNotNullOrEmpty()]
[string] $NodeName = 'CORE-O-DSCPull.CORE.local',
[ValidateNotNullOrEmpty()]
[string] $RegistrationKey, #same as the one used to setup pull server in previous configuration
[ValidateNotNullOrEmpty()]
[string] $ServerName = 'CORE-O-DSCPull.CORE.local' #node name of the pull server, same as $NodeName used in previous configuration
)
Node $NodeName
{
Settings
{
RefreshMode = 'Pull'
}
ConfigurationRepositoryWeb CORE-O_PullSrv
{
ServerURL = "https://$ServerName`:8080/PSDSCPullServer.svc" # notice it is https
RegistrationKey = $RegistrationKey
ConfigurationNames = #('Basic')
}
}
}
I apply the LCM settings to my pull-server without a problem.
I can create a simple basic.mof and use DSC to apply it. All this works fine.
Next, I create another meta.mof file for another node to let it register to my pull-server. I use the same configuration as above except for the nodename, which I change to the name of the other node. I use the command:
Set-DscLocalConfigurationManager -ComputerName <nodename> -path <pathtonewmetamof>
This command works correctly. That machine can then use DSC to apply the same basic.mof without problems.
Here comes the problem:
I restart my pull server and node, create a new basic.mof and try to apply this to both my machines. This procedure works fine on the pull server itself, but my node can no longer apply the basic.mof, because it will no longer register with my pull-server. I have replicated this many times, where I would install both machines from scratch and configure them. Every time I restart my machines, registration stops working. See the error below:
Registration of the Dsc Agent with the server https://CORE-O-DSCPull.CORE.local:8080/PSDSCPullServer.svc failed. The underlying error is: Failed to register Dsc
Agent with AgentId 1FE837AA-C774-11E6-80B5-9830B2A0FAC0 with the server
https://core-o-dscpull.core.local:8080/PSDSCPullServer.svc/Nodes(AgentId='1FE837AA-C774-11E6- 80B5-9830B2A0FAC0'). .
+ CategoryInfo : InvalidResult: (root/Microsoft/...gurationManager:String) [], CimException
+ FullyQualifiedErrorId : RegisterDscAgentCommandFailed,Microsoft.PowerShell.DesiredStateConfiguration.Commands.RegisterDscAgentCommand
+ PSComputerName : CORE-O-DC.CORE.local
So, my problem is that registration seems to work fine until I reboot the pull server. Does anyone have any idea what can cause this issue?
For those wondering if I managed to fix this, yes I did.
It appears to be a bug in WMF5.0 and I was only using WMF5.1 on the pullserver. Not on the node. So I had to update that and now it is working.
As explained in this blog entry the low-level problem is that WMF 5.0 uses TLS 1.0 to communicate with the server, while WFM 5.1 does no longer support TLS 1.0.
In the aforementioned entry you will find two solutions: one that implies upgrading WMF in every and each of the nodes, and another that allows less secure connections by modifying the register in the server.

Connecting to an azure Service Fabric App

I'm trying to debug why my Service Cluster App is stuck during the upgrade session.
I've looked up how to do it with powershell and I found the command:
Get-ServiceFabricApplicationUpgrade fabric:/My.Fabric.App.Name
This command throws the error:
Get-ServiceFabricApplicationUpgrade : Cluster connection instance is null
So naturally, I tried connecting to the cluster with:
Connect-ServiceFabricCluster myfabric.westeurope.cloudapp.azure.com:19000
But I got:
WARNING: Failed to contact Naming Service. Attempting to contact Failover Manager Service...
WARNING: Failed to contact Failover Manager Service, Attempting to contact FMM...
False
Connect-ServiceFabricCluster : One or more errors occurred.
At line:1 char:1
+ Connect-ServiceFabricCluster myfabric.westeurope.cloudapp.azure.com:19000
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Connect-ServiceFabricCluster], AggregateException
+ FullyQualifiedErrorId : CreateClusterConnectionErrorId,Microsoft.ServiceFabric.Powershell.ConnectCluster
Service fabric is annoying.. Please help? :\
UPDATE
It's probably because my fabric is secured and I have a client cert that I have to use to connect.
I tried the following config for the command:
$connectArgs = #{ ConnectionEndpoint = 'myfabric.westeurope.cloudapp.azure.com:19000'; X509Credential = $True; StoreLocation = 'CurrentUser'; StoreName = "MY"; ServerCommonName = "myfabric.westeurope.cloudapp.azure.com"; FindType = 'FindByThumbprint'; FindValue = "DEADBEEFDEADBEEFDEADBEEFDEADBEEF"; SkipChecks = $True }
But Get-ServiceFabricApplicationUpgrade still doesn't work.
Success!
With the following arguments:
$connectArgs = #{ ConnectionEndpoint = 'myfabric.westeurope.cloudapp.azure.com:19000';
X509Credential = $True;
StoreLocation = "CurrentUser";
StoreName = "My";
ServerCommonName = "myfabric.westeurope.cloudapp.azure.com";
FindType = 'FindByThumbprint';
FindValue = "81EBFC23D456130C0CA99952484240EA2385F0C3";
ServerCertThumbprint = "DEADBEEFDEADBEEFDEADBEEFDEADBEEF" }
Connect-ServiceFabricCluster #connectArgs

Override Creation for Monitors and Rules

I want to create PowerShell scripts to override some parameter of my monitor and rule. I used the below code, but I have some errors. I want override my overidable parameter not enabled or something else. How can I doe this?
$mps = Get-SCOMManagementPack | ? {$_.Name -like "test"}
$overrideMp = Get-SCOMManagementPack -DisplayName "Overrides"
$overridename = "testmonitor.Overrides"
$monitor = 'testmonitor'
$override = New-Object Microsoft.EnterpriseManagement.Configuration.ManagementPackMonitorPropertyOverride($overrideMp,$overridename)
$override.Monitor = $monitor
$override.Property = 'WarningThreshold'
$override.Value = 80
$override.DisplayName = "Overrides"
$overrideMp.Verify()
$overrideMp.AcceptChanges()
Errors:
error1: Exception setting "Property": "Cannot convert value "WarningThreshold" to
type "Microsoft.EnterpriseManagement.Configuration.ManagementPackMonitorProperty".
Error: "Unable to match the identifier name WarningThreshold to a valid enumerator
name. Specify one of the following enumerator names and try again: Enabled,
TraceEnabled, Algorithm, AlgorithmPercentage, DefaultState, GenerateAlert,
AutoResolve, AlertPriority, AlertOnState, AlertSeverity, AlertMessage,
AlertParameter1, AlertParameter2, AlertParameter3, AlertParameter4,
AlertParameter5, AlertParameter6, AlertParameter7, AlertParameter8,
AlertParameter9, AlertParameter10, MemberInMaintenance, MemberUnavailable,
IgnoreMemberInMaintenance, IgnoreMemberUnavailable""
At line:1 char:2
+ $override.Property = $parametername
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], SetValueInvocationException
+ FullyQualifiedErrorId : ExceptionWhenSetting
error2 : Exception calling "AcceptChanges" with "0" argument(s): "Database error.
MPInfra_p_ManagementPackInstall failed with exception: Failed to validate item:
testrule1"
At line:193 char:1
+ $MP.AcceptChanges()
+ ~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ManagementPackException
The error message looks rather clear to me. There is no property WarningThreshold in the ManagementPackMonitorProperty enumeration. I don't have much experience with SCOM, but you probably need to override the property AlertOnState for monitors where the property AlertSeverity has the value Warning.
Try something along the lines of this:
$mps | Get-SCOMMonitor | Where-Object {
# (other selection criteria) -and
$_.AlertSettings.AlertSeverity -eq 'Warning'
} | ForEach-Object {
$ctx = Get-SCOMClass -Id $_.Target.Id
# ...
$override = New-Object ...
$override.Monitor = $_
$override.Property = 'AlertOnState'
$override.Value = 80
$override.Context = $ctx
# ...
}
Code adopted from here (probably the same place where you found it). Not sure if this works, though. Like I said, I have very little experience with SCOM, and I don't have a SCOM server available for testing.
I'll try to debug it tomorrow in the office.
BTW, there is a third-party tool for override management called MPTuner: http://mpwiki.viacode.com/default.aspx?g=mptuner
It's free so you should try.
Roman.
It's quite confusing, but there are two different type of overrides for each workflow type. For a monitor there are:
MonitorPropertyOverride
MonitorConfigurationOverride
You are using the first one, wgich is for standard parameters only, like Enabled, for example. For any custom parameters use Configuration Override.