How to set up client in Powershell 5.0 DSC Pull Mode - powershell

I have 2 servers set up for DSC, Both running Powershell 5.0 and Server 12 R2, DSCPULL is configured as a DSC Pull Server over HTTP, DSCIIS is the client.
On DSCIIS i am trying to set it up so that it downloads the config from the Pull server via a configuration names, i have taken code from the MSDN website and altered slightly to my requirements but it still isn't working.
[DSCLocalConfigurationManager()]
configuration PullClientConfigID
{
Node localhost
{
Settings
{
RefreshMode = 'Pull'
RefreshFrequencyMins = 30
RebootNodeIfNeeded = $true
}
ConfigurationRepositoryWeb DSCPULL
{
ServerURL = 'http://DSCPULL:8080/PSDSCPullServer.svc'
RegistrationKey = 'test'
ConfigurationNames = #('WebServer')
AllowUnsecureConnection = $true
}
}
}
PullClientConfigID -OutputPath c:\Configs\TargetNodes
Start-DscConfiguration C:\Configs\TargetNodes -ComputerName localhost -wait -Verbose
The error i receive is
Start-DscConfiguration : The computer-specific MOF file for computer localhost does not exist in the current directory.
At line:1 char:1
+ Start-DscConfiguration C:\Configs\TargetNodes -ComputerName localhost ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Start-DscConfiguration], ArgumentException
+ FullyQualifiedErrorId : System.ArgumentException,Microsoft.PowerShell.DesiredStateConfiguration.Commands.StartDscConfiguration
Command
I have tried changing "Node Localhost" to the server name and then run the last line with the correct "ComputerName" but i get the same error.

I should have been using Set-DSCLocalConfigurationManager not Start-DSCConfiguration
Set-DSCLocalConfigurationManager localhost –Path C:\Configs\TargetNodes –Verbose

Related

Configuring Remote Desktop Services remotely via powershell

Trying to manage our Remote Desktop Services installation using PowerShell and we're running into an issue where the commands in the RemoteDeskop module and the RemoteDesktopServices module do not appear to work when being run via Invoke-Command. Basically it appears that these functions do not work when run in a remote session.
The script below gets the following error:
The RD Connection Broker server is not available. Verify that you can
connect to the RD Connection Broker server.
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Get-RDServer
+ PSComputerName : AWSELABSDevX13.LABSDEV.com
$server = "OUR_SERVER"
$connection_broker = "OUR_SERVER"
$collectionName ="COLLECTION"
$admin_user = "FULLY_QUALIFIED_DOMAIN_USER"
$password = "PASSWORD"
$password_sec = ConvertTo-SecureString $password -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential ($admin_user, $password_sec)
$sb =
{
function Test-IsAdmin {
([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")
}
if (Test-IsAdmin) {
""
"You are running with Administrator access."
""
} else {
""
"You do not have admin access."
""
}
whoami /priv
Import-Module RemoteDesktop
Import-Module RemoteDesktopServices
Get-RDServer
}
Invoke-Command -Credential $cred -ComputerName $connection_broker -ScriptBlock $sb

Getting terraform null_resource local-exec to run a powershell install-module

this probably evil to do, but in order to setup a managed identity in our azure db we are using the null_resource like this:
# https://www.terraform.io/docs/providers/null/resource.html
# This technique was stolen from https://stackoverflow.com/a/54523391/442773
resource "null_resource" "create-sql-user" {
triggers = {
db = azurerm_sql_database.x.id
}
# https://www.terraform.io/docs/provisioners/local-exec.html
provisioner "local-exec" {
# https://learn.microsoft.com/en-us/powershell/module/sqlserver/Invoke-Sqlcmd?view=sqlserver-ps
# Adding the Managed Identity to the database as a user and assign it the roles of db_datareader and db_datawriter
# NOTE: This is using the executing users credentials to connect to the db, this may not work if this is executed from a service principal within a devops pipeline
# NOTE: this requires powershell to have the SqlServer module installed. We tried a bunch of things to make it so it'd auto install the module but couldn't get it to work
command = <<EOF
Invoke-Sqlcmd `
-Query "CREATE USER [${azurerm_app_service.x.name}] FROM EXTERNAL PROVIDER; ALTER ROLE db_datareader ADD MEMBER [${azurerm_app_service.x.name}]; ALTER ROLE db_datawriter ADD MEMBER [${azurerm_app_service.x.name}];" `
-ConnectionString "Server=tcp:${azurerm_sql_server.x.fully_qualified_domain_name},1433;Initial Catalog=${azurerm_sql_database.x.name};Persist Security Info=False;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Authentication=Active Directory Integrated;" `
EOF
interpreter = ["PowerShell", "-Command"]
}
}
the problem is the requirement to have Invoke-Sqlcmd available, but that's there only by Install-Module SqlServer out of band w/ terraform. I tried a few different things in the command to make this happen. like:
# https://www.terraform.io/docs/provisioners/local-exec.html
provisioner "local-exec" {
# https://learn.microsoft.com/en-us/powershell/module/sqlserver/Invoke-Sqlcmd?view=sqlserver-ps
# Adding the Managed Identity to the database as a user and assign it the roles of db_datareader and db_datawriter
command = "Install-Module -Name SqlServer -AcceptLicense -SkipPublisherCheck -Force -AllowClobber -Scope CurrentUser;"
interpreter = ["PowerShell", "-ExecutionPolicy", "Bypass", "-Command"]
}
Error: Error running command 'Install-Module -Name SqlServer -AcceptLicense -SkipPublisherCheck -Force -AllowClobber -Scope CurrentUser;': exit status 1. Output: Install-Module : The 'Install-Module' command was found in the module 'PowerShellGet', but the module could not be loaded. For more information, run 'Import-Module PowerShellGet'.
so switching the command to
command = "Import-Module PowerShellGet; Install-Module -Name SqlServer -AcceptLicense -SkipPublisherCheck -Force -AllowClobber -Scope CurrentUser;"
but that lead to this output
Error: Error running command 'Import-Module PowerShellGet; Install-Module -Name SqlServer -AcceptLicense -SkipPublisherCheck -Force -AllowClobber -Scope CurrentUser;': exit status 1. Output: Import-Module : The specified module 'C:\program
files\powershell\6\Modules\PackageManagement\fullclr\Microsoft.PackageManagement.dll' was not loaded because no valid
module file was found in any module directory.
At line:1 char:1
+ Import-Module PowerShellGet; Install-Module -Name SqlServer -AcceptLi ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ResourceUnavailable: (C:\program file...eManagement.dll:String) [Import-Module], FileNot
FoundException
+ FullyQualifiedErrorId : Modules_ModuleNotFound,Microsoft.PowerShell.Commands.ImportModuleCommand
PackageManagement\Get-PackageProvider : The term 'PackageManagement\Get-PackageProvider' is not recognized as the name
of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included,
verify that the path is correct and try again.
At C:\program files\powershell\6\Modules\PowerShellGet\PSModule.psm1:2926 char:26
+ ... $nugetProvider = PackageManagement\Get-PackageProvider -ErrorA ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (PackageManagement\Get-PackageProvider:String) [], CommandNotFoundExcept
ion
+ FullyQualifiedErrorId : CommandNotFoundException
PackageManagement\Get-PackageProvider : The term 'PackageManagement\Get-PackageProvider' is not recognized as the name
of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included,
verify that the path is correct and try again.
At C:\program files\powershell\6\Modules\PowerShellGet\PSModule.psm1:2940 char:40
+ ... ailableNugetProviders = PackageManagement\Get-PackageProvider -Name $ ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (PackageManagement\Get-PackageProvider:String) [], CommandNotFoundExcept
ion
+ FullyQualifiedErrorId : CommandNotFoundException
Exception calling "ShouldContinue" with "2" argument(s): "Object reference not set to an instance of an object."
At C:\program files\powershell\6\Modules\PowerShellGet\PSModule.psm1:3115 char:8
+ if($Force -or $psCmdlet.ShouldContinue($shouldContinueQueryMessag ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : NullReferenceException
Install-Module : NuGet provider is required to interact with NuGet-based repositories. Please ensure that '2.8.5.201'
or newer version of NuGet provider is installed.
At line:1 char:30
+ ... erShellGet; Install-Module -Name SqlServer -AcceptLicense -SkipPublis ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [Install-Module], InvalidOperationException
+ FullyQualifiedErrorId : CouldNotInstallNuGetProvider,Install-Module
one thing i'm wondering is if powershell versions 6 vs 5 is getting in the way here somehow...
EDIT:
I believe you're using the wrong intepreter, try switching Powershell to pwsh to use powershell 6 as an interpreter.
provisioner "local-exec" {
...
interpreter = ["pwsh", "-Command"]
...
}
I'm unsure about the underlying infrastructure where you require powershell to run. It seems like you're using powershell 6.
I also use a null-provider resource, calling into a script, passing in arguments and then creating a user. One advantage of that is that I know which powershell verson I am running (core) as the trigger command is pwsh.
I'll show you how I'm creating the null resource and a snippet of the script, in the hopes it might help.
Null resource for calling a script responsible for creating the user
resource "null_resource" "create_sql_user" {
provisioner "local-exec" {
command = ".'${path.module}\\scripts\\create-sql-user.ps1' -password \"${random_password.sql_password.result}\" -username \"${var.sql_username}\" -sqlSaConnectionString \"${var.sql_server_connectionstring}\" -databaseName \"${azurerm_sql_database.db.name}\" "
interpreter = ["pwsh", "-Command"]
}
depends_on = [azurerm_sql_database.db]
}
create-sql-user.ps1
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[string]
$password,
[Parameter(Mandatory = $true)]
[string]
$username,
[Parameter(Mandatory = $true)]
[string]
$sqlSaConnectionString
)
Install-Module -Name SqlServer -Force
$sqlCmd = "CREATE LOGIN $username WITH PASSWORD = '$password'; ALTER LOGIN $username enable"
Invoke-Sqlcmd -ConnectionString $sqlSaConnectionString -Query $sqlCmd
...
Extras:
In this case I'm generating the sql password using the random resource. One can use similar approach for username:
resource "random_password" "sql_password" {
length = 54
special = true
override_special = "$%#&*()"
}

Powershell DSC Cannot invoke the Invoke-DscResource cmdlet

I'm trying to use DSC to configure the nodes in my service fabric cluster virtual machine scale set. Doing some registry edits, to keep it small I only show one below. When I run the functions manually by themselves they work fine. When trying to nest them inside one function I get an error.
configuration ServiceFabricNode {
Node localhost
{
SSLPerfectForwardSecrecyTLS12 ConfigureSSL {}
ServiceFabricAntivirusExclusions AntiVirusExclusions {}
}
}
configuration SSLPerfectForwardSecrecyTLS12 {
Import-DscResource –ModuleName PSDesiredStateConfiguration
Import-DscResource -ModuleName GraniResource
# Disable Multi-Protocol Unified Hello
Registry "DisableServerMultiProtocolUnifiedHello"
{
Key = "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\Multi-Protocol
Unified Hello\Server"
ValueName = "Enabled"
ValueType = "Dword"
ValueData = "0"
Ensure = "Present"
Force = $true
}
}
configuration ServiceFabricAntivirusExclusions {
Import-DscResource -ModuleName WindowsDefender
[string[]]$exclusionPath = "C:\Program Files\Microsoft Service abric\","D:\SvcFab\";
Invoke-DscResource -Name WindowsDefender -ModuleName WindowsDefender -Method Set -Property #{ IsSingleInstance = 'Yes'; ExclusionPath = $exclusionPath }
[string[]]$exlusionProcess = "Fabric.exe","FabricHost.exe","FabricInstallerService.exe","FabricSetup.exe","FabricDeployer.exe","ImageBuilder.exe","FabricGateway.exe","FabricDCA.exe","FabricFAS.exe","FabricUOS.exe","FabricRM.exe","FileStoreService.exe";
Invoke-DscResource -Name WindowsDefender -ModuleName WindowsDefender -Method Set -Property #{ IsSingleInstance = 'Yes'; ExclusionProcess = $exlusionProcess }
}
ServiceFabricNode
Results into
Compilation errors occurred while processing configuration 'ServiceFabricNode'. Please review the errors reported in error stream and modify your configuration code
appropriately.
At C:\Windows\system32\WindowsPowerShell\v1.0\Modules\PSDesiredStateConfiguration\PSDesiredStateConfiguration.psm1:3917 char:5
+ throw $ErrorRecord
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (ServiceFabricNode:String) [], InvalidOperationException
+ FullyQualifiedErrorId : FailToProcessConfiguration
With debug enabled it shows the real exception
Cannot invoke the Invoke-DscResource cmdlet. The Invoke-DscResource cmdlet is in progress and must return before Invoke-DscResource can be invoked. Use -Force option if
that is available to cancel the current operation.
+ CategoryInfo : NotSpecified: (root/Microsoft/...gurationManager:String) [], CimException
+ FullyQualifiedErrorId : MI RESULT 1
+ PSComputerName : localhost
I cannot find a -Force option and Google seems to filter out all errors for Invoke-DscResource or I'm the first one using it. Does anyone know a solution? Maybe I don't have to use Invoke-DscResource for the WindowsDefender module, but I don't see another way.
I figured it out with the following blog information http://nanalakshmanan.com/blog/Composite-Resources-Explained/
WindowsDefender is a Composite-Resource
configuration ServiceFabricAntivirusExclusions
{
Import-DscResource -ModuleName WindowsDefender
[string[]]$exclusionPath = "C:\Program Files\Microsoft Service Fabric\","D:\SvcFab\";
[string[]]$exlusionProcess = "Fabric.exe","FabricHost.exe","FabricInstallerService.exe","FabricSetup.exe","FabricDeployer.exe","ImageBuilder.exe","FabricGateway.exe","FabricDCA.exe","FabricFAS.exe","FabricUOS.exe","FabricRM.exe","FileStoreService.exe";
WindowsDefender x
{
IsSingleInstance = 'Yes';
ExclusionPath = $exclusionPath;
ExclusionProcess = $exlusionProcess;
}
}

Powershell RunAs Administrator in a SSIS Package

Am trying to remote connect to a server and run a powershell script to open ports in windows firewall in a SSIS Execute Process task
Here is the Powershell code:
$computername = hostname
$script = {
$FireWallRule_1 = Get-NetFirewallRule
$par1 = #{
DisplayName = "DAC"
LocalPort = 1434
Direction="Inbound"
Protocol ="TCP"
Action = "Allow"
}
$FireWallRule_2 = Get-NetFirewallRule
$par2 = #{
DisplayName = "MSSQLSERVER"
LocalPort = 1433
Direction="Inbound"
Protocol ="TCP"
Action = "Allow"
}
$par1.Localport = 1434
$par1.DisplayName = "DAC"
if (-not $FireWallRule_1.DisplayName.Contains($par1.DisplayName)) {New-NetFirewallRule #par1}
$par2.LocalPort = 1433
$par2.DisplayName = "MSSQLSERVER"
if (-not $FireWallRule_2.DisplayName.Contains($par2.DisplayName)) {New-NetFirewallRule #par2}
}
Invoke-Command -ScriptBlock $script -ComputerName $computername
Here is the error i got:
Connecting to remote server [SERVERNAME] failed with the following error message: Access is denied. For more information, see the
aboute_Remote_Troubleshooting Helptopic.
+ CategoryInfo : OpenError: (SERVERNAME:String) [], PSRemotingTransportException
+ FullyQualifiederrorId : AccessDenied, PSSessionStateBroken
I have tried to run the PS script locally and its working, the account that run ssis is local administrator on the target server. Is it possible to RunAs Administrator in a SSIS Package?
Thanks Håkan

Why does setting the 'QueuingEnabled' of a COM+ app remotely by powershell cause the save to fail?

I have this powershell script which is creating COM+ applications on a remote machine:
$credentials = Get-Credential -Message "Test" -User "DOMAIN\User"
$roleRM = new-pssession -computername MACHINE -credential $credentials
Invoke-Command -Session $roleRM -scriptblock `
{
$comAdmin = New-Object -ComObject ("COMAdmin.COMAdminCatalog.1")
$comApplicationCollection = $comAdmin.GetCollection("Applications")
$comApplicationCollection.Populate()
$comApplication = $comApplicationCollection.Add()
$comApplication.Value("Name") = "Server"
$comApplication.Value("ApplicationAccessChecksEnabled") = 0
$comApplication.Value("AccessChecksLevel") = (0)
$comApplication.Value("Authentication") = (1)
$comApplication.Value("Identity") = "DOMAIN\User"
$comApplication.Value("Password") = "password"
$comApplication.Value("QueuingEnabled") = 1
$comApplication.Value("QueueListenerEnabled") = 1
$comApplicationCollection.SaveChanges()
}
but when I try and run it it fails with this error:
Exception calling "SaveChanges" with "0" argument(s): "An operations error occurred.
"
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ComMethodTargetInvocation
+ PSComputerName : MACHINE
If I exclude this line:
$comApplication.Value("QueuingEnabled") = 1
then it saves and creates the application correctly. If I run this script locally then it creates the application correctly on the local machine with QueuingEnabled=1, but always fails when running on a remote machine.
Why might this be?
Try setting "Authentication" to 4 or 6 and see if that changes anything. See this.