Powershell DSC - Unzip file to remote destination - powershell

My goal is to create a Powershell DSC configuration to unzip a file - from my local computer - to a remote directory on a Hyper-V Win10 VM (I've already shared that destination folder). But, right now, I still have some problem to insert the VM credentials inside the .ps1. This is my code:
Configuration CopyTest {
Node 'localhost'
{
User Admin
{
UserName = "Admin"
Password = "Password"
Ensure = "Present"
}
Archive ArchiveExample {
Ensure = 'Present'
Path = 'C:\Users\myuser\Documents\test.zip'
Destination = '\\DESKTOP-HEFLNJ6\destination'
}
}
}
Can anyone suggest me a way to insert the Windows credentials (of the remote machine) inside the Powershell script?
Thanks for your time...hope you can help!

you will have to use credential in you DSC configuration.
Below documentations will help you to achieve it.
https://learn.microsoft.com/en-us/powershell/dsc/runasuser
below is a small example which uses credential in a DSC configuration.
configuration FileCopy
{
Param(
[PSCredential]$Credential
)
node localhost
{
File CopyFile{
Ensure = 'Present'
DestinationPath = '\\server\share'
SourcePath = 'c:\sourcepath'
PsDscRunAsCredential = $Credential
}
}
}

Related

Terraform GCP unable to run metadata command for windows instance to create a user

Trying to create a user which can be used in connection to move some files , when i try to create a user while creating a instance using metadata resource get created successfully but metadata command is not executed.
`resource "google_compute_instance" "win-dev-instance" {
project = "my_pro_1"
zone = "eu-west2-b"
name = "win-dev-instance"
machine_type = "f1-micro"
boot_disk {
initialize_params {
image = "windows-server-2016-r2-dc-v20191210"
}
}
network_interface {
network = "default"
access_config {
}
}
metadata {
windows-startup-script-cmd = "net user /add devuser PASSWORD & net localgroup adminstrators devuser /add"
}
}`
In your example, there is a typo adminstrators, it should be administrators.
Solution
resource "google_compute_instance" "win-dev-instance" {
project = "my_pro_1"
zone = "eu-west2-b"
name = "win-dev-instance"
machine_type = "n1-standard-2"
boot_disk {
initialize_params {
image = "windows-server-2016-dc-v20191210"
}
}
network_interface {
network = "default"
access_config {}
}
metadata = {
windows-startup-script-cmd = "net user /add devuser Abc123123 & net localgroup administrators devuser /add"
}
}
I test without success the solution based on windows-startup-script-cmd. Also this script will be excuted every time the instance restart.
I think the best solution is to use the metadata with the windows-keys key as described here. The solution is to generate a double key, one will be used by gcp to generate the password and the second to decrypt it on reception

unable to use ssh key when spawning digitalocean droplet using terraform

I am using terraform v0.10.6 to spin up a droplet on digitalocean. I am referencing a key and SSH fingerprint that has already been added to digitalocean in my terraform config (copied below). I am able to log onto existing droplets using this ssh key but not on a newly formed droplet (SSH simply fails). Any thoughts on how to troubleshoot this so that when I launch the droplet via terraform, I should be able to log onto the droplet via the key that has already been added on digitalocean (and visible on DO console). Currently, the droplet appears on the digitalocean admin console but I am never able to SSH onto the server (connection gets denied).
test.tf
# add base droplet with name
resource "digitalocean_droplet" "do-mail" {
image = "ubuntu-16-04-x64"
name = "tmp.validdomain.com"
region = "nyc3"
size = "1gb"
private_networking = true
ssh_keys = [
"${var.ssh_fingerprint}",
]
connection {
user = "root"
type = "ssh"
private_key = "${file(var.private_key)}"
timeout = "2m"
}
provisioner "remote-exec" {
inline = [
"export PATH=$PATH:/usr/bin",
"sudo apt-get update",
]
}
}
terraform.tfvars
digitalocean_token = "correcttoken"
public_key = "~/.ssh/id_rsa.pub"
private_key = "~/.ssh/id_rsa"
ssh_fingerprint = "correct:finger:print"
provider.tf
provider "digitalocean" {
token = "${var.digitalocean_token}"
}
variables.tf
##variables used by terraform
# DO token
variable "digitalocean_token" {
type = "string"
}
# DO public key file location on local server
variable "public_key" {
type = "string"
}
# DO private key file location on local server
variable "private_key" {
type = "string"
}
# DO ssh key fingerprint
variable "ssh_fingerprint" {
type = "string"
}
I was able to setup a new droplet with the SSH key at initialization time when I specified the digitalocean token as an environment variable (as opposed to relying on the terraform.tfvars file).

DSC Script resource does not read environement variable

I have a DSC configuration which install nodejs, adds npm to environment Path variable and then installs a npm module.
xPackage InstallNodeJs {
Name = 'Node.js'
Path = "$env:SystemDrive\temp\node-v4.4.7-x64.msi"
ProductId = '8434AEA1-1294-47E3-9137-848F546CD824'
Arguments = "/quiet"
}
Environment AddEnvironmentPaths
{
Name = "Path"
Ensure = "Present"
Path = $true
Value = "$env:SystemDrive\ProgramData\npm"
}
Script UpgradeNpm {
SetScript = {
& npm install --global --production npm-windows-upgrade
& npm-windows-upgrade --npm-version 3.10.6
}
TestScript = {
$npmVersion = & npm -v
return $npmVersion -eq "3.10.6"
}
GetScript = {
return {#{Result = "UpgradeNpm"}}
}
}
Installing nodejs and adding npm to Path variable seems to be successful. Both nodejs and npm location are added to Path and I can use them both in powershell and cmd.
However, Script resource returns that 'npm' is not recognized as internal or external command ...
the same is for node which is used inside npm-windows-upgrade script file.
Do you know why Script resource cannot read newly added Path entires?
The Environment DSC resource implementation makes the change by updating the values stored in the registry (with the exception of variables targeting Process). Changes made to environment variables stored in the registry are not reflected in the current session (read once, on session start).
You can affect values stored in the current session by:
Using System.Environment.SetEnvironmentVariable ([System.Environment]::SetEnvironmentVariable)
Modifying $env:<VariableName>
Of those, only the first allows you to write a persistent change. The latter can be considered a volatile change.
It's an odd limitation of the resource, I've looked at this before and felt it a little lacking.
There's no dependency information in there, so you can't count on the Environment resource running before the Script resource. There's not enough information in your post to tell if that's the case for sure, but you should consider controlling it anyway:
xPackage InstallNodeJs {
Name = 'Node.js'
Path = "$env:SystemDrive\temp\node-v4.4.7-x64.msi"
ProductId = '8434AEA1-1294-47E3-9137-848F546CD824'
Arguments = "/quiet"
}
Environment AddEnvironmentPaths
{
Name = "Path"
Ensure = "Present"
Path = $true
Value = "$env:SystemDrive\ProgramData\npm"
DependsOn = '[xPackage]InstallNodeJs'
}
Script UpgradeNpm {
SetScript = {
& npm install --global --production npm-windows-upgrade
& npm-windows-upgrade --npm-version 3.10.6
}
TestScript = {
$npmVersion = & npm -v
return $npmVersion -eq "3.10.6"
}
GetScript = {
return {#{Result = "UpgradeNpm"}}
}
DependsOn = '[Environment]AddEnvironmentPaths'
}
Can you share which version of DSC you are using? You can get this by doing a $PSVersionTable on the PowerShell console. I am able to add to the PATH variable and use it in a script resource.
configuration NPMTest
{
Environment AddEnvironmentPaths
{
Name = 'Path'
Ensure = 'Present'
Path = $true
Value = "$env:SystemDrive\ProgramData\npm"
}
Script p
{
GetScript = {#{}}
TestScript = {return $false}
SetScript = {$a = & a.ps1 ; Write-Verbose $a -Verbose}
}
}
The script a.ps1 was executed fine even though I am not specifying the full path to the script.

Configure a DSC Resource to restart

I have a DSC resource that installs dotnet feature and then installs an update to dotnet.
In the Local Configuration Manager I have set RebootNodeIfNeeded to $true.
After dotnet installs, it does not request a reboot (even used xPendingReboot module to confirm this).
Configuration WebServer
{
WindowsFeature NetFramework45Core
{
Name = "Net-Framework-45-Core"
Ensure = "Present"
}
xPendingReboot Reboot
{
Name = "Prior to upgrading Dotnet4.5.2"
}
cChocoPackageInstaller InstallDotNet452
{
name = "dotnet4.5.2"
}
}
This is a problem as dotnet doesn't work properly with our app unless the server has been rebooted and we are trying to make these reboots happen automatically no user input required.
Is there any way to make a resource push to the localdscmanager (LCM) that it needs a reboot when there's something being installed?
I have found the below command
$global:DSCMachineStatus = 1
Which sets a reboot. but I'm unsure as to how to use it to reboot right after the 4.5 module is installed.
Normally when I install .Net it works without rebooting, but if you want to force your configuration to reboot it after it installs it you can do the following. It won't work for drift (.net being removed after initial installation.) During configuration drift, the configuration will still install .net, but the script resource I added to reboot will believe it has already rebooted.
The DependsOn is very important here, you don't want this script running before the WindowsFeature has run successfully.
configuration WebServer
{
WindowsFeature NetFramework45Core
{
Name = "Net-Framework-45-Core"
Ensure = "Present"
}
Script Reboot
{
TestScript = {
return (Test-Path HKLM:\SOFTWARE\MyMainKey\RebootKey)
}
SetScript = {
New-Item -Path HKLM:\SOFTWARE\MyMainKey\RebootKey -Force
$global:DSCMachineStatus = 1
}
GetScript = { return #{result = 'result'}}
DependsOn = '[WindowsFeature]NetFramework45Core'
}
}
To get $global:DSCMachineStatus = 1 working, you first need to configure Local Configuration Manager on the remote node to allow Automatic reboots. You can do it like this:
Configuration ConfigureRebootOnNode
{
param (
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[String]
$NodeName
)
Node $NodeName
{
LocalConfigurationManager
{
RebootNodeIfNeeded = $true
}
}
}
ConfigureRebootOnNode -NodeName myserver
Set-DscLocalConfigurationManager .\ConfigureRebootOnNode -Wait -Verbose
(code taken from colin's alm corner)

Cargo plugin for Gradle ignoring configured port

I have the following configuration :
cargo {
containerId = deployContainerId
port = jbossManagementPort
deployable {
file = tasks.getByPath(':frontend:war').archivePath
context = 'xxxxxx'
}
remote {
hostname = 'localhost'
username = 'xxxxxxx'
password = 'xxxxxxx'
}
local {
homeDir = file(jbossHome)
timeout = 60000
}
}
When I invoke Gradle with
gradle -PjbossManagementPort=12345 -PdeployContainerId=jboss7x -PjbossHome=/opt/jboss cargoRedeployRemote
The configured port is ignored. It still tries to connect to 9999. I have tried variants, such as
gradle -Pcargo.port=12345 -PdeployContainerId=jboss7x -PjbossHome=/opt/jboss cargoRedeployRemote
And
gradle -Pcargo.jboss.management-native.port=12345 -PdeployContainerId=jboss7x -PjbossHome=/opt/jboss cargoRedeployRemote
But neither has any effect.
How do I tell Cargo to use a different port than the default?
The solution is to use -D for the cargo-property rather than -P:
gradle -Dcargo.jboss.management-native.port=12345 -PdeployContainerId=jboss7x -PjbossHome=/opt/jboss cargoRedeployRemote
A possible solution that you can define in your gradle build to handle this issue.
remote {
//You can define custom cargo properties here
containerProperties {
property 'cargo.jboss.management-native.port', 12345
}
hostname = 'localhost'
username = 'xxxxxxx'
password = 'xxxxxxx'
}