Linux executes a command on a remote Windows server without SSH/Telnet - deployment

I am building a Jenkins server. One of the deployment steps is to execute a command on the production server to download the UAT-tested artifacts to the required folders. Jenkins is running on CentOS Linux while the production server is running Windows 2008 R2.
However, my client does not want to install any software into the production server, therefore executing commands via SSH is not possible. The client had an unpleasant experience with using Telnet before. It is an insecure service which has already been disabled on the server.
Other than using SSH and Telnet, are there other ways to execute a command on a remote machine? I was thinking of creating a task that is triggered by a specific event, but how to raise the event on the server remotely seems not an easy job.

I can think of four different solutions:
Have a network share on the production machine that your Jenkins server can put a trigger file into. Have a scheduled task that checks for that file and triggers the download.
Have a scheduled task on the production machine poll the Jenkins server for new files. Powershell can be used to query the Jenkins REST api.
If the production machine has IIS, get Jenkins to trigger an asp.net script, do a form POST to a cgi script, or upload a trigger file. curl and wget on CentOS will help there.
As a last resort, add another windows machine into the mix. Install SSH onto it. Use SSH from Jenkins to the new machine, then powershell from the new machine to the production machine.
If you decide on step 4, I use Power Shell to run commands on a remote machine.
PS2.0 is installed on Windows 2008 R2 by default.
Here is an example of how I do it.
$username = 'user'
$password = 'password'
$appHost = 'hostname'
$dest = 'C:\Unpack\'
$archive = "C:\Releases\new release.7z"
$securePass = ConvertTo-SecureString -AsPlainText $password -Force
$cred = New-Object System.Management.Automation.PSCredential -ArgumentList $username,$securePass
"Create PowerShell Session"
$appSession = New-PSSession -ComputerName $appHost -Credential $cred -Authentication CredSSP
invoke-command -session $appSession -scriptblock { param($dest,$archive) & 'C:\Program Files (x86)\7-Zip\7z.exe' x -bd -aoa """-oc:\$dest""" """c:\$dest\$archive"""} -args $dest,$archive
$remotelastexitcode = invoke-command -session $appSession -ScriptBlock { $lastexitcode }
if ( $remotelastexitcode -ne 0 )
{
"Archive Extraction Failed. Is a file locked or open?"
exit -1
}

Related

Powershell and Jenkins - Execute Powershell Script as another user

I have an environment formed by a Jenkins Server, a couple of Jenkins Slaves (windows) and several remote windows computers all part of the same domain.
I need to run a jenkins job, which executes a powershell snippet consisted of several functions (part of a custom modules loaded on the Jenkins Slave) against other windows remote computers in the same domain (which do not have the modules installed).
These modules needs to run under a specific domain account with permissions to access the remote computers.
If I logon with on any of the jenkins slave (with that specific domain account) everything works fine.
By default, Jenkins executes the job on the slave using the NT authority\system account which, of course, returns me denied access errors.
Question: is there a way to tell Jenkins to execute the Job on the windows slave with another specific Domain Account and not the NT Authority\System one?
Tried already:
Invoke-command using credentials: this is not an option since the remote computers do not have the modules
Impersonation: tried a couple of functions found on the PS gallery but do not work
You can run powershell as a process in a script and call that from Jenkins. In the script also you can use like:
$username = 'username'
$password = 'password'
$securePassword = ConvertTo-SecureString $password -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential $username,$securePassword
Start-Process Powershell.exe -Credential $credential
Hope it helps.

how to execute PowerShell commands from Windows server A so that it runs on Windows server B

Basically, i have PowerShell on both servers, is there a way to make a connection between both servers in such a way that when I run a command on PowerShell of Server A then it also runs on PowerShell of Server B.
I am new to PowerShell. Any help would be great.
You can use the New-PSSession-cmdlet in combination with the Invoke-Command-cmdlet
First of all create a remote session object:
$remoteSession = New-PSSession -ComputerName "YourComputerName" -Credential (Get-Credential)
Afterwards, you can use the $remoteSession object to execute commands on the remote via:
$servicesOnTheRemote = Invoke-Command -Session $remoteSession -Verbose -ScriptBlock { Get-Service * }
Invoke-Command runs Get-Service on the remote host, fetches the service state, serializes the data, and sends the data to the calling host. Based on that $servicesOnTheRemote includes the service state of the remote.
Also checkout this usefull cheatsheet.
Hope that helps.

How to delete a folder on an Azure App Service website using Octopus Deploy

I am setting up an automated deployment project for a Sitecore website using TeamCity and Octopus Deploy (v. 3.3.6).
Before deploying to the App Service using a "Deploy an Azure Web App" step, I would like to delete one folder on that site (/site/wwwroot/App_Config/Include or D:\home\site\wwwroot\App_Config\Include).
Is there a built-in mechanism in Octopus to do this? I have tried using a Powershell script, but that runs on the server, not on Azure. Is there a way to run a Powershell script on Azure while deploying?
Or can I use the "Run an Azure Powershell Script" to do file manipulations on an App Service website without having to authenticate (since Octopus is doing the authentication)?
Or are there any other/better solutions to solve this without having to save credentials in a file on the Build Server?
I would prefer not to use FTP for this, if at all possible.
I would do this:
Create a on-demand webjob in Azure and upload a powershell script that can clean up the folder to your Webapp. Try to keep this ps script simple, use base cmdlet commands, not all ps modules would run in azure.
How: https://blogs.msdn.microsoft.com/nicktrog/2014/01/22/running-powershell-web-jobs-on-azure-websites/
You still need your teamcity or octopus to run a powershell line to kick off the webjob. With that, the work load is not on octopus server anymore but you still need the same azure authentication process for the powershell line.
How: http://www.nullfactory.net/2015/05/start-azure-webjobs-on-demand/
"Run an Azure Powershell Script" in octopus helps you load the Azure Powershell module and do the Azure-Subscription trick, so you don't need to include the library within the script or re-authenticate. It still runs locally but step #2 fits this well.
Hope this can help you.
In the end I decided to use FTP anyway. Even though I quite like Kai Zhao's suggestion, I preferred to keep all things related to the automated deploy on the deploy server instead of having to put and maintain scripts in different locations.
I used the following Powershell FTP Client Module and installed it on our build server: https://gallery.technet.microsoft.com/scriptcenter/PowerShell-FTP-Client-db6fe0cb
And I used this script to do the actual delete and run it as a step in Octopus:
$AzureAppService is a variable in Octopus which changes depending on the
environment.
Import-Module PSFTP
$username = $AzureAppService
$password = ConvertTo-SecureString "************" -AsPlainText -Force
$cred = new-object -typename System.Management.Automation.PSCredential `
-argumentlist $username, $password
$ftpserver = "***url_to_your_ftp_server**"
$folderToDelete = "/site/wwwroot/App_Config/Include"
Set-FTPConnection -Credentials $cred -Server $ftpserver -Session MyFTPSession -UsePassive
$Session = Get-FTPConnection -Session MyFTPSession
Try
{
Remove-FTPItem -Session $Session -Path $folderToDelete -Recurse
}
Catch
{
Write-Warning "There was an error while trying to remove the folder:"
Write-Warning $_.Exception.Message
Write-Warning $_.Exception.ItemName
}

Install remotely with powershell

I want to build a script that will Install remotely HP OM agent. Is there any good way to Install it, without having the install files on the remote computer?
this script will install remotely the HP agents for list of servers. I thought to copy the files from my computer to each server and after that to install it. I'm sure there is a better way to do it.
To install the agent I need to run the command :
cscript "\c:\pathToTheAgentFile" -i -a -minprecheck
Using Invoke-Command with the ScriptBlock parameter should accomplish this task so long as a silent install method is used.
$ComputersList = #("computer","names","here","replace","me")
$PathToShare = "\\path\to\install_replace_me.exe"
$CommonLocalComputerPath = "C:\replace_me.exe"
$SilentInstallArgs = "/example","/replace"
$AdministratorCreds = [System.Management.Automation.PSCredential]::Empty
$ComputersList | ForEach-Object {
Invoke-Command -ComputerName $_ -ScriptBlock { Copy-Item $Using:PathToShare -Destination $Using:CommonLocalComputerPath -Credential $Using:AdministratorCreds;
Start-Process $Using:CommonLocalComputerPath -ArgumentList $Using:SilentInstallArgs -Credential $Using:AdministratorCreds} -Credential $AdministratorCreds
}
The above script will prompt for administrative credentials, authenticate to a remote share that holds the installer from the remote computer, copy the installer to the remote computer, and then start the installer on the remote computer. You will have to verify the installs manually as it will not return any data except in the event of a terminating error. The script will have to be modified to point to the correct locations for your environment.

Restart IIS on remote machine using Powershell

I have a TFSserver and a QAserver. I am using autodeployment using TFS and have a powershell script that do the requirement.
But I have a issue in restarting the QA server IIS from the same power shell script.
i am doing the following set of commands for restarting the IIS.
/*struser is in the administrator group of the QAserver
$cred = New-Object System.Management.Automation.PSCredential ("$QAserver$struser", $password )
$session = new-pssession $oceane_server -Auth Negotiate -Credential $cred
/* Some deployment script */
invoke-command -session $session -ScriptBlock {iisreset /stop}
Following error appears :
Access denied, you must be an administrator of the remote computer to use this
command. Either have your account added to the administrator local group of
the remote computer or to the domain administrator global group.
I could not find the solution for this. Any help would be appreciable.
The quick work around is to open all the ports of your server and run iisreset [MACHINENAME] /stop.
For powershell remoting, I use credssp because it allows the double-hop. Also, did you set your execution policy to bypass?
Set-ExecutionPolicy Bypass