Azure ARM DSC - install VS2017 remote debugger - visual-studio-2017

I'm creating a Service Fabric cluster for a dev environment which requires the Visual Studio 2017 Remote Debugger to be installed and running as a service on each node using Powershell DSC.
Our DSC script successfully copies the vs2017 remote tools installer and does the unattended install but we are struggling to get it running as a service and with the correct firewall settings.

Here is what we ended up going with:
# Download and configure Chocolaty
cChocoInstaller InstallChoco
{
InstallDir = "C:\choco"
}
# Download and install VS2017 Remote Debugger
cChocoPackageInstaller InstallRemoteDebugger
{
Name = "visualstudio2017-remotetools"
Version = "15.0.26430.2"
Source = “https://github.com/chocolatey/chocolatey-coreteampackages/tree/master/manual/visualstudio2017-remotetools”
DependsOn = "[cChocoInstaller]installChoco"
}
# Install the remote debugger and run as a service
Script ConfigureRemoteDebugger {
GetScript = { #{ Result = "" } }
TestScript = {
$msvsmonPathx64 = 'C:\Program Files\Microsoft Visual Studio 15.0\Common7\IDE\Remote Debugger\x64\msvsmon.exe'
$serviceName = "msvsmon150"
$result = $true
# Validate the VS2017 Remote Debugger is installed to the harddrive
$result = $result -and (Test-Path $msvsmonPathx64)
# Verify the service exists and is running
if ($service = Get-Service -Name $serviceName -ErrorAction SilentlyContinue) {
if ($service.Status -eq "Running") {
$result = $result -and $true
}
else {
$result = $result -and $false
}
}
else {
$result = $result -and $false
}
return $result
}
SetScript =
{
# Run as service
$startDebugger = $true
$remoteDebugExe = "`"C:\Program Files\Microsoft Visual Studio 15.0\Common7\IDE\Remote Debugger\x64\rdbgservice.exe`" msvsmon150"
$serviceName = "msvsmon150"
$serviceDisplayName = "Visual Studio 2017 Remote Debugger"
$serviceDescription = "Allows members of the Administrators group to remotely debug server applications using Visual Studio. Use the Visual Studio Remote Debugging Configuration Wizard to enable this service."
if (!(Get-Service -Name msvsmon150 -ErrorAction SilentlyContinue)) {
New-Service -Name $serviceName -BinaryPathName $remoteDebugExe -DisplayName $serviceDisplayName -Description $serviceDescription
}
if ($startDebugger -eq $false) {
Set-Service -Name $serviceName -StartupType Manual
}
else {
Set-Service -Name $serviceName -StartupType Automatic
Start-Service -Name $serviceName
}
}
Credential = $serviceAccountCredential
DependsOn = "[cChocoPackageInstaller]InstallRemoteDebugger"
}
Note: Your DSC will likely need to configure the firewall to allow the Remote Debugger otherwise you will not be able to connect.
Big shoutout to Chocolatey for making the download+install process so easy.

Related

Trying to use PowerShell to install Microsoft sql management studio (ssms)

I'm trying to install Microsoft sql server management studio on my AWS windows server and I keep getting this error on PowerShell
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$here = pwd
$software = "SQL Server Management Studio";
$installed = (Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Where { $_.DisplayName -eq $software }) -ne $null
#If SQSS was not installed before, it will be download required files and install it.
If(-Not $installed)
{
Write-Host "'$software' is NOT installed.";
wget https://aka.ms/ssmsfullsetup -outfile "SSMS-Setup-ENU.exe"
.\SSMS-Setup-ENU.exe /install /quiet /norestart
}
#If SQSS was installed before, it will try to update it to the newer version, if available.
#If no updates available, it will do nothing.
else
{
Write-Host "'$software' is installed."
if ( Test-Path -Path $here\SSMS-Setup-ENU.exe )
{
.\SSMS-Setup-ENU.exe /update /quiet /norestart
}
else {
wget https://aka.ms/ssmsfullsetup -outfile "SSMS-Setup-ENU.exe"
.\SSMS-Setup-ENU.exe /update /quiet /norestart
}
}
Here is the error I keep getting
wget : The remote name could not be resolved: 'download.microsoft.com'
At C:\Temp\mqss-1.ps1:12 char:1
wget https://aka.ms/ssmsfullsetup -outfile "SSMS-Setup-ENU.exe"
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
Continuing from my comment. The installer does not offer an /update switch, so you can just use install for both. I would use Start-Process to execute the command and let it provide the array of arguments to it.
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Push-Location $env:temp
$software = "SQL Server Management Studio"
$installed = (Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Where-Object DisplayName -eq $software )
If(-Not $installed){
Write-Verbose "'$software' is NOT installed, installing" -Verbose
}
else{
Write-Verbose "'$software' is installed, updating" -Verbose
}
Write-Verbose "Downloading SSMS-Setup-ENU.exe" -Verbose
try{
Invoke-WebRequest https://aka.ms/ssmsfullsetup -OutFile '.\SSMS-Setup-ENU.exe' -ErrorAction Stop
}
catch{
Write-Warning "Error downloading file: $($_.exception.message)"
break
}
$arguments = "/install","/quiet","/norestart"
Write-Verbose "Executing 'SSMS-Setup-ENU.exe $arguments'" -Verbose
try{
$result = Start-Process .\SSMS-Setup-ENU.exe -ArgumentList $arguments -PassThru -Wait
}
catch{
Write-Warning $_.exception.message
}
switch -Exact($result.ExitCode){
1603 {
Write-Verbose "Reboot is required" -Verbose
}
0 {
Write-Verbose "Installation successful" -Verbose
}
default{
Write-Verbose "Installation was not successful" -Verbose
}
}

Is it possible to download files/data during the build pipeline on Azure DevOps?

We would like to transfer the development via azure devops to another company and we ask ourselves whether not only new releases can be pushed through this pipeline. But also data could be downloaded from the productive environment via the azure devops or aws devops pipeline?
I researched myself but found nothing about it.
does any of you have more information on this?
Thank you
Is it possible to download files/data during the build pipeline on Azure DevOps?
In Azure DevOps, there isn't a task to download files/data, but you can use the PowerShell task to connect to FTP server and download files.
For detailed information, you can refer to this similar question.
- task: PowerShell#2
inputs:
targetType: 'inline'
script: |
#FTP Server Information - SET VARIABLES
$ftp = "ftp://XXX.com/"
$user = 'UserName'
$pass = 'Password'
$folder = 'FTP_Folder'
$target = "C:\Folder\Folder1\"
#SET CREDENTIALS
$credentials = new-object System.Net.NetworkCredential($user, $pass)
function Get-FtpDir ($url,$credentials) {
$request = [Net.WebRequest]::Create($url)
$request.Method = [System.Net.WebRequestMethods+FTP]::ListDirectory
if ($credentials) { $request.Credentials = $credentials }
$response = $request.GetResponse()
$reader = New-Object IO.StreamReader $response.GetResponseStream()
while(-not $reader.EndOfStream) {
$reader.ReadLine()
}
#$reader.ReadToEnd()
$reader.Close()
$response.Close()
}
#SET FOLDER PATH
$folderPath= $ftp + "/" + $folder + "/"
$files = Get-FTPDir -url $folderPath -credentials $credentials
$files
$webclient = New-Object System.Net.WebClient
$webclient.Credentials = New-Object System.Net.NetworkCredential($user,$pass)
$counter = 0
foreach ($file in ($files | where {$_ -like "*.txt"})){
$source=$folderPath + $file
$destination = $target + $file
$webclient.DownloadFile($source, $target+$file)
#PRINT FILE NAME AND COUNTER
$counter++
$counter
$source
}
Certificate comes from: PowerShell Connect to FTP server and get files.
You should use artifacts when it is inside your "environment".
Otherwise you can use the normal command line tools like git or curl and wget this depends on your build agent.

Why Am I Seeing These Errors in My SSRS Powershell Script in One Environment but Not Another?

I have a Powershell Script I'm working on for post-migration SSRS report administration tasks.
In this particular scenario we have a DEV environment (where I've been primarily testing) which hosts a single instance of SSRS, and a Prod environment which is a scaled out deployment across 4 nodes.
I'm new to Powershell (just discovered it 2 days ago...) and the script I have is pretty simple:
Clear-Host 
$Username = "domain\myUsername"
$Password = "myPassword"
$Cred = New-Object System.Management.Automation.PSCredential -ArgumentList #($Username,(ConvertTo-SecureString -String $Password -AsPlainText -Force))
# Dev Connection String
$webServiceUrl = 'http://DEVwebServer.domain.com/reportserver/reportservice2010.asmx?WSDL'
# Prod Connection String
# $webServiceUrl = 'http://PRODwebServerNode1.domain.com/reportserver/reportservice2010.asmx?WSDL'
$rs = New-WebServiceProxy -Uri $webServiceUrl -Credential $Cred
 
$reports = $rs.ListChildren("/Some Folder Under Root", $true) | Where-Object { $_.TypeName -eq "Report" }
$type = $ssrsProxy.GetType().Namespace;
$schedDefType = "{0}.ScheduleDefinition" -f $type;
$schedDef = New-Object ($schedDefType)
$warning = #();
foreach ($report in $reports) {
$sched = $rs.GetExecutionOptions($report.Path, [ref]$schedDef);
$snapShotExists = $rs.ListItemHistory($report.Path);
if($sched -eq "Snapshot") {
Write-Host "Following report is configured to run from Snapshot:" -ForegroundColor Yellow
Write-Host ("Report Name: {0}`nReport Path: {1}`nExecution Type: {2}`n" -f $report.Name, $report.Path, $sched)
if ($snapShotExists) {
Write-Host "Does Snapshot Exist..?`n" -ForegroundColor Yellow
Write-Host "Yes!`tNumber of Snapshots: " $snapShotExists.Count -ForegroundColor Green
$snapShotExists.CreationDate
Write-Host "`n------------------------------------------------------------"
}
elseif (!$snapShotExists) {
Write-Host "Does Snapshot Exist..?`n" -ForegroundColor Yellow
Write-Host ("No!`n") -ForegroundColor Red
Write-Host "Creating Snapshot.......`n" -ForegroundColor Yellow
$rs.CreateItemHistorySnapshot($report.Path, [ref]$warning);
Write-Host "Snapshot Created!`n" -ForegroundColor Green
$snapShotExists.CreationDate
Write-Host "`n------------------------------------------------------------"
}
}
}
The purpose of the script is simply to recursively iterate over all of the reports for the given folder in the $reports variable, check to see if the execution type is set to "Snapshot", if it is check to see if a "History Snapshot" exists, and if one does not exist, create one.
When I run this in Dev it works just fine, but when I run in PROD I get the following error repeated for each $report in my foreach loop:
Any ideas on why this would work in one and not the other and how to overcome this error?
I was able to get this working on the Prod instance by making some adjustments using this answer as a guide:
By updating my call to New-WebServiceProxy to add a Class and Namespace flag, I was able to update the script in the following ways:
...
# Add Class and Namespace flags to New-WebServiceProxy call
$rs = New-WebServiceProxy -Class 'RS' -Namespace 'RS' -Uri $webServiceUrl -Credential $Cred
 
$reports = $rs.ListChildren("/Business and Technology Solutions", $true) | Where-Object { $_.TypeName -eq "Report" }
# Declare new "ScheduleDefintion object using the Class declared in the New-WebServiceProxy call
$schedDef = New-Object RS.ScheduleDefinition
$warning = #();
foreach ($report in $reports) {
# Referencing the "Item" property from the ScheduleDefinition
$execType = $rs.GetExecutionOptions($report.Path, [ref]$schedDef.Item)
...
I don't think the adding of the Class and Namespace flags on the New-WebServiceProxy call was exactly what did it, as I think it's just a cleaner way to ensure you're getting the proper Namespace from the WebService. Maybe just a little sugar.
I think the key change was making sure to the "Item" property from the schedule definition object, although I'm not sure why it was working in Dev without doing so...

Execute scripts under a different user context in vRealize Automation 7.2

I am building blueprints in vRealize Automation 7.2 and I need to be able to execute code from a remote location as part of the process. I know I can use encrypted properties to provide the credentials of a user and then execute scripts in a different user context, but is that my only option? I see in vRealize Orchestrator that I can change the credential of the user executing a workflow, but I'm not sure that's my best option either.
I found a way by mapping a drive on the deployed machine to the network location using powershell scripts.
$driveLetter = "U"
$networkPath = "\\network\share"
$userName = "domain\username"
$password = "password"
$psDrive = Get-PSDrive -Name $driveLetter
if ($psDrive)
{
Remove-PSDrive $psDrive
}
$token = $password | ConvertTo-SecureString -AsPlainText -Force
$credentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $userName, $token -ErrorAction Stop
$output = New-PSDrive -Name $driveLetter -Root $networkPath -PSProvider FileSystem -Credential $credentials -Persist -Scope Global
$driveLetter = $output.Name + ":"
I was then able to map the resulting drive letter to other steps install location using vRealize Automation software components and binding the properties to this component's property by marking the property's Binding box checked and setting the Value to ConnectionStep_1~driveLetter property.

Workflow subscription service does not return any value

I am trying to start the SharePoint 2013 workflow thru the powershell csom model. I have browsed and got many links with the same promising coding. But in my case it is not working. I have tried both in on premises sharepoint 2013 and sharepoint online but none them worked out. Below is the code:
Set-ExecutionPolicy Unrestricted
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.WorkflowServices.dll"
# Specify tenant admin and site URL
$SiteUrl = "https://spoffice365.sharepoint.com/"
$ListName = "Test"
$UserName = "myusername"
$SecurePassword = Read-Host -Prompt "Enter password" -AsSecureString
# Connect to site
$ClientContext = New-Object Microsoft.SharePoint.Client.ClientContext($SiteUrl)
$credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName, $SecurePassword)
$ClientContext.Credentials = $credentials
$ClientContext.ExecuteQuery()
# Get List and List Items
$List = $ClientContext.Web.Lists.GetByTitle($ListName)
$ListItems = $List.GetItems([Microsoft.SharePoint.Client.CamlQuery]::CreateAllItemsQuery())
$ClientContext.Load($List)
$ClientContext.Load($ListItems)
$ClientContext.ExecuteQuery()
# Retrieve WorkflowService related objects
$WorkflowServicesManager = New-Object Microsoft.SharePoint.Client.WorkflowServices.WorkflowServicesManager($ClientContext, $ClientContext.Web)
$WorkflowSubscriptionService = $WorkflowServicesManager.GetWorkflowSubscriptionService()
$WorkflowInstanceService = $WorkflowServicesManager.GetWorkflowInstanceService()
$ClientContext.Load($WorkflowServicesManager)
$ClientContext.Load($WorkflowSubscriptionService)
$ClientContext.Load($WorkflowInstanceService)
$ClientContext.ExecuteQuery()
# Get WorkflowAssociations with List
$WorkflowAssociations = $WorkflowSubscriptionService.EnumerateSubscriptionsByList($List.Id)
$ClientContext.Load($WorkflowAssociations)
$ClientContext.ExecuteQuery()
# Prepare Start Workflow Payload
$Dict = New-Object 'System.Collections.Generic.Dictionary[System.String,System.Object]'
# Loop List Items to Start Workflow
For ($j=0; $j -lt $ListItems.Count; $j++){
$msg = [string]::Format("Starting workflow {0}, on ListItemId {1}", $WorkflowAssociations[0].Name, $ListItems[$j].Id)
Write-Host $msg
#Start Workflow on List Item
$Action = $WorkflowInstanceService.StartWorkflowOnListItem($WorkflowAssociations[0], $ListItems[$j].Id, $Dict)
$ClientContext.ExecuteQuery()
}
The below $WorkflowAssociations does not return any value both in sharepoint 2013 and sharepoint online always comes as empty, even though the $List.Id passed correctly and verified that list has approver workflow configured.
$WorkflowAssociations = $WorkflowSubscriptionService.EnumerateSubscriptionsByList($List.Id)
$ClientContext.Load($WorkflowAssociations)
$ClientContext.ExecuteQuery()
And also would like to learn how to pass approver name to the below method:
$WorkflowInstanceService.StartWorkflowOnListItem($WorkflowAssociations[0], $ListItems[$j].Id, $Dict)