Compare a file size between 2 servers (Unix & Windows) - unix

I need to write a Windows batch file to resolve the below issue.
I need to make sure that a file is completely transferred from it's origin server (Unix) to the target server (Windows).
I am trying to compare the file size between the two servers, the solution needs to be in a Windows batch file (I am having trouble with connecting to a remote Unix server using SSH in a DOS batch file)

From the fact you can use SSH, I assume you also have an SFTP access.
You can use following PowerShell script using WinSCP .NET assembly.
param (
$sessionUrl = "sftp://user:mypassword;fingerprint=ssh-rsa-xxxxxxxxx...=#example.com/",
$localPath = "C:\path\file.dat",
$remotePath = "/path/file.dat"
)
$localSize = (Get-Item $localPath).Length
Write-Host "$localPath has $localSize bytes"
# Load WinSCP .NET assembly
Add-Type -Path (Join-Path $PSScriptRoot "WinSCPnet.dll")
# Setup session options
$sessionOptions = New-Object WinSCP.SessionOptions
$sessionOptions.ParseUrl($sessionUrl)
$session = New-Object WinSCP.Session
# Connect
$session.Open($sessionOptions)
$remoteSize = $session.GetFileInfo($remotePath).Length
$session.Dispose()
Write-Host "$remotePath has $remoteSize bytes"
# Compare cheksums
if ($localSize -eq $remoteSize)
{
Write-Host "Match"
$result = 0
}
else
{
Write-Host "Does NOT match"
$result = 1
}
exit $result
Or even better, compare file checksums, not just size, if your server support that, see:
Verify checksum of a remote file against a local file over SFTP/FTP protocol
(I'm the author of WinSCP)

Related

How to HTTPS (SSL) with self-hosted ASP.NET Core 2 app (httpsys)

I wrote a little ASP.NET Core 2 application. It runs as a service, so no IIS. It runs on a PC with Windows 7 SP1.
var host = WebHost.CreateDefaultBuilder(args)
.UseContentRoot(pathToContentRoot)
.UseHttpSys(options =>
{
options.Authentication.Schemes = AuthenticationSchemes.None;
options.Authentication.AllowAnonymous = true;
options.MaxConnections = null;
options.MaxRequestBodySize = 30000000;
options.UrlPrefixes.Add("http://*:5050");
})
.UseStartup<Startup>()
.UseApplicationInsights()
.Build();
if (isService)
{
host.RunAsService();
}
else
{
host.Run();
}
As you can see, I want to listen on port 5050. This is working fine without SSL.
My question is, how can I enable https for my application? Again: No IIS, no Domain-Name (no internet connection). Communication is just inside the internal network, so I want to use a self-signed certificate.
I read the documentation (HTTP.sys documentation;Netsh Commands;New-SelfSignedCertificate), but there is always something different to my situation (they use Krestel, or it is for using IIS). Also, I dont know how to get the App-ID (needed for netsh) for my Application. I tryed this: StackOverflow Get GUID but it doesn't work.
var assembly = typeof(Program).Assembly;
// following line produces: System.IndexOutOfRangeException
var attribute = (GuidAttribute)assembly.GetCustomAttributes(typeof(GuidAttribute), true)[0];
var id = attribute.Value;
Console.WriteLine(id);
So I am a bit confused about all the possabilitys and different configurations. And the docs don't consider my specific case.
I created a certificate, and I guess I need to store it on the "my" Store. (Where is that? cert:\LocalMachine\My) And then I need to assign my Applicaion ID and Port to it.
But I have no idea how to do that exactly. Can anyone help?
So I solve the problem in the following way:
First, if you want to know your own GUID, you will get it with the following code:
var id = typeof(RuntimeEnvironment).GetTypeInfo().Assembly.GetCustomAttribute<GuidAttribute>().Value;
Create a SelfSigned Certificate
Now create a SelfSigned-Certificate (Skip this if you already got one, or purchased one)
Run the following OpenSSL command to generate your private key and public certificate. Answer the questions and enter the Common Name when prompted.
openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out certificate.pem
Combine your key and certificate in a PKCS#12 (P12) bundle:
openssl pkcs12 -inkey key.pem -in certificate.pem -export -out certificate.p12
Install the certificate on the client:
For Windows 8 and higher:
Add Certificate to Windows Cert Store with PowerShell
PS C:> $certpwd = ConvertTo-SecureString -String "passwort" -Force –AsPlainText
PS C:> Import-PfxCertificate –FilePath D:\data\cert\certificate.p12 cert:\localMachine\my -Password $certpwd
Get Fingerprint (Hash) of certificate
PS C:\WINDOWS\system32> dir Cert:\LocalMachine\my
Install certificate (replace Hash, IP and Port with your values)
PS C:\WINDOWS\system32> $guid = [guid]::NewGuid()
PS C:\WINDOWS\system32> $certHash =
"A1D...B672E"
PS C:\WINDOWS\system32> $ip = "0.0.0.0"
PS C:\WINDOWS\system32> $port = "5050"
PS C:\WINDOWS\system32> "http add sslcert ipport=$($ip):$port
certhash=$certHash appid={$guid}" | netsh
You are done.
For Windows 7
Add Certificate to Windows Cert Store (note: use .pem file for this operation, because .p12 file seems to be not supported from certutil)
.\certutil.exe -addstore -enterprise -f "Root" C:\lwe\cert\certificate.pem
If his line throws the following error:
SSL Certificate add failed, Error 1312
A specified logon session does not exist. It may already have been terminated.
You have to do the steps manually (please insert the .p12 file when doing it manually, not .pem) :
Run mmc.exe
Go to File-> Add/Remove Snap-In
Choose the Certificates snap-in.
Select Computer Account
Navigate to: Certificates (Local Computer)\Personal\Certificates
Right click the Certificates folder and choose All Tasks -> Import.
Follow the wizard instructions to select the certificate. Be sure you check the export checkbox during wizard.
To get the hash of yor certificate, run the Internet Explorer, press Alt + X and go to Internet Options -> Content -> Certificates. Search your certificate and read the hash.
Now you can run the same commands as for Windows 8+:
Install certificate (replace Hash, IP and Port with your values)
PS C:\WINDOWS\system32> $guid = [guid]::NewGuid()
PS C:\WINDOWS\system32> $certHash =
"A1D...B672E"
PS C:\WINDOWS\system32> $ip = "0.0.0.0"
PS C:\WINDOWS\system32> $port = "5050"
PS C:\WINDOWS\system32> "http add sslcert ipport=$($ip):$port
certhash=$certHash appid={$guid}" | netsh
Edit your Code
After all, you have to set the UrlPrefixes to https. So in your Program.cs file you need to have:
var host = WebHost.CreateDefaultBuilder(args)
.UseContentRoot(pathToContentRoot)
.UseHttpSys(options =>
{
options.Authentication.Schemes = AuthenticationSchemes.None;
options.Authentication.AllowAnonymous = true;
options.MaxConnections = null;
options.MaxRequestBodySize = 30000000;
options.UrlPrefixes.Add("https://*:5050");
})
.UseStartup<Startup>()
.UseApplicationInsights()
.Build();

Trying to replicate IBM Mainframe SFTP upload with JSch ChannelSftp

I am trying to use Jsch Sftp Channel to upload a file to an IBM Mainframe, and the directory has to be "//", where the mainframe will automatically route the file where it needs to go.
In an sftp command session on the IBM mainframe, I can do this:
sftp myuser#1.2.3.4
connecting to 1.2.3.4...
myuser#1.2.3.4's password:
sftp> pwd
Remote working directory: /users/home/myuser
sftp> cd //
sftp> pwd
Remote working directory: //
sftp> put "#12345.abcdef.xxx.xxx"
uploading #12345.abcdef.xxx.xxx to //#12345.abcdef.xxx.xxx
#12345.abcdef.xxx.xxx 100% 403 0.4KB/s 00:00
So I created a JSch sftp session (version 0.1.5.1) to attempt the same upload, but it does not work:
JSch jsch = new JSch();
Session session = jsch.getSession("myuser", "1.2.3.4");
session.setPassword("mypass");
session.connect();
Channel channel = session.openChannel("sftp");
channel.connect();
ChannelSftp sftp = (ChannelSftp)channel;
log.info(" user home pwd " + sftp.pwd()); //prints /users/home/myuser
sftp.cd("//")
log.info(" pwd after cd " + sftp.pwd()); //only prints /
sftp.put(filename); //get sftp error, no such file
So I cannot get to that // structure through the JSch library. Is there a certain mode or flag that needs to be set for the sftp session to know it's on a mainframe?
I have no issue at all doing a JSch sftp session to my /users/home/myuser directory, just can't get it to go to the //
I had a similar issue with pseudofolder "//".
Avoid this sftp.cd("//") and better try this sftp.put("/-/"+filename); instead, that solved my problem. Hopefully will help you as well.
Try it without calling ChannelSftp.cd():
ChannelSftp sftp = (ChannelSftp)channel;
sftp.put("//" + filename); // Put to //#12345.abcdef.xxx.xxx
The SFTP protocol doesn't actually have a chdir-type operation. At the protocol level, pathnames which don't start with "/" are always interpreted relative to the directory where the SFTP session started. There's no protocol command to change that starting directory.
SFTP clients, including Jsch, emulate chdir-like behavior client-side. When you call ChannelSftp.cd(), Jsch stores the new remote directory locally. When you later call put() or get(), and give a pathname that doesn't start with "/", Jsch prepends the remote directory onto the filename and passes the altered name to the remote server.
I think what's happening to you is that Jsch's chdir emulation is being a little too clever. When you call cd("//"), it's collapsing the "//" into a single "/" and storing that. Then you call put() for a relative pathname, it's prepending the single "/" instead of the double "//" that you want.
Based on inspecting the Jsch source code, it looks like Jsch never alters remote names that start with "/". If you call put("//somefile"), Jsch should use the name you specified as-is.

Powershell remote install .exe file errors and not finding setup.iss file

Hi I am trying to figure out how to install .exe files to 5 server machine but I am having trouble trying to install silently on my own machine.
I have this command
Invoke-Command -ScriptBlock {Start-Process -FilePath \\xxx-STUDENT3-W7\Users\bkoo004\Documents\test\ccleaner402.exe \r}
but I can't find the setup.iss file in the Windows folder.
Also when I use this command
Invoke-Command -computername xxxxxxxxxxx.edu -ScriptBlock {start-process -filepath "\\xxx-S
TUDENT3-W7\Users\bkoo004\Documents\test\ccleaner402.exe" } -Credential $cred
It gives me an error saying that
This command cannot be executed due to the error: The network name cannot be found.
+ CategoryInfo : InvalidOperation: (:) [Start-Process], InvalidOperationException
+ FullyQualifiedErrorId : InvalidOperationException,Microsoft.PowerShell.Commands.StartProcessCommand
But I know that network name is right because when I run
Invoke-Command -computername xxxxxxxxxxx.edu -ScriptBlock {get-process } -Credential $cred
It returns the get-process of that server.
I figured that for not getting the setup.iss file it is because the program that i am trying to install doesn't use installshield but for the error trying to run start-process on my remote server I have no idea what it is.
Not sure if you are running into the double-hop problem on not, but it sounds like you are. So I though I'd give you a little more information about it. The Bob Loblaw version.
What is a server and what is a client? A server, it accepts things, is the computer you remote onto. A client, it gives things, is the computer you use to do the remoting. So in the command Invoke-Command -computername xxxxxxxxxxx.edu ..., "xxxxxxxxxxx.edu" is the server.
From your description, it looks like you already ran the command Enable-PSRemoting on your server. With remoting enabled on the server you should be able to do Enter-PSSession -ComputerName xxxxxxxxxxx.edu and have an interactive command prompt on the client.
If you enter a remote session and do Get-ChildItem "\\ComputerName\Share" the command is going to fail (it fails for safety reasons). That's the double-hop, because you're going from one computer to another. The network share is another computer. So you're going like this:
Client -> Server -> Network Share
Hippity-Hoppity
You need to setup more "things" to fix the double-hop. First on your server(s) you need to run the command Enable-WSManCredSSP Server so it will accept credentials from clients. Second on your client(s) you need to run the command Enable-WSManCred -Role Client -DelegateComputer * so it gives out your credential to servers.
Now with CredSSP configured to give and accept credentials, you should have resolved the doulbe-hop.
Enter-PSSession -ComputerName Computer1 -Authentication Credssp -Credential (Get-Credential)
Now you should be able to get to your network shares from the remote session Get-ChildItem "\\ComputerName\Share".
Hope this helps you out a bit.
P.S. There is always money in the banana stand.

How do I change multiple unix passwords in one script/batch file?

I connect to 8 different unix servers from Windows, using connection type 'SSH' in putty. I use the same username/password for each server.
Currently when I need to change passwords (every 60 days), I need to open putty, select the session I want to connect to, type my current password (in the putty window that opens), type "passwd", enter my current password, and then enter my new password.
Then I exit and repeat the process 7 times.
How can I convert this to an automated process where I simply need to supply a script/batch process with my old and new password?
Here is how I automated the process:
Download and install ActiveTCL Community Edition (download the 32 bit version, even if you are on 64 bit windows, as the 64 bit version does not have "Expect" which is what you need to run the automated script)
Open the tclsh85 executable that was created by the install
Run this command "teacup install Expect" (note, this is case sensitive. You may need to setup special http settings if you receive an error and/or are on vpn or using a proxy)
Download Putty's "plink.exe" and either place it in the bin directory of ActiveTCL (default install directory is "C:\Tcl\bin") or alter your "Path" environment variable to include the path to this executable (wherever you downloaded plink.exe). This is the command-line version of Putty which your script will use.
Anywhere on your drive, create a text file named "servers.txt" with a list of the servers (one per line). They should all share the same password, as the script will login to all of them with the same password (that you supply), and change the password to the one you supply.
In the same directory as "servers.txt" create a new text file called "ChangePassword.tcl" (or whatever you want to call it, but be sure its file type is "tcl"). Right click the file and edit in notepad (or whatever text editor you prefer) and paste this script in it.
package require Expect
exp_log_user 0
set exp::nt_debug 1
proc changepw {host user oldpass newpass} {
spawn plink $host
log_user 0
expect {
"login as: " { }
}
exp_send "$user\r"
expect "sword: "
exp_send "$oldpass\r"
expect "\$ "
exp_send "passwd\r"
expect "sword: "
exp_send "$oldpass\r"
expect "sword: "
exp_send "$newpass\r"
expect "sword: "
exp_send "$newpass\r"
set result $expect_out(buffer)
exp_send "exit\r"
return $result
}
label .userlbl -text "Username:"
label .oldpasslbl -text "\nOld Password: "
label .newpasslbl -text "\nNew Password: "
set username "username"
entry .username -textvariable username
set oldpassword "oldpassword"
entry .oldpassword -textvariable oldpassword
set newpassword "newpassword"
entry .newpassword -textvariable newpassword
button .button1 -text "Change Password" -command {
set fp [open "servers.txt" r]
set file_data [read $fp]
close $fp
set data [split $file_data "\n"]
foreach line $data {
.text1 insert end "Changing password for: $line\n"
set output [changepw $line $username $oldpassword $newpassword]
.text1 insert end "$output\n\n"
}
}
text .text1 -width 50 -height 30
pack .userlbl .username .oldpasslbl .oldpassword .newpasslbl .newpassword .button1 .text1
Save the script and then launch the ChangePassword.tcl file.
Here is a picture of what it looks like when you open the ChangePassword.tcl file:
The rest should be self explanatory. Note the program does not output when your password change was successful but it will tell you when it fails. Also note, this was my first tcl script (and first time using Expect) so the script is by no means "optimized" and could probably be improved but it gets the job done. Feel free to edit, or make suggestions/improvements.
Sounds like you want Expect, an extension of TCL that can mimic typing at a keyboard for a console application. See the examples for how to do this.
Now there is something you've written that worries me:
I connect to 8 different unix servers, using connection type 'SSH' in putty. I use the same username/password for each server.
Why aren't you using SSH keys for automating the logon?
Great article! Just elaborating on step-3. Please note the commands to provide Proxy server information in case "teacup install Expect" fails due to connectivity issue:
%teacup install Expect
Resolving Expect ... Not found in the archives.
...
Aborting installation, was not able to locate the requested entity.
child process exited abnormally
% teacup list teacup
0 entities found
Problems which occurred during the operation:
* http://teapot.activestate.com :
{connect failed connection refused} {can't read
"state(sock)": no such element in array while executing
"fileevent $state(sock) writable {}"} NONE
% teacup proxy "abcproxy.mycorp.com" 8080
Proxying through abcproxy.mycorp.com # 8080
% set http_proxy_user MyNetworkID
MyNetworkID
% set http_proxy_pass MyNetworkPassword
MyNetworkPassword
% teacup list teacup
entity name version platform
----------- ------ --------------- ----------
application teacup 8.5.16.0.298388 win32-ix86
----------- ------ --------------- ----------
1 entity found
% teacup install Expect
Resolving Expect ... [package Expect 5.43.2 win32-ix86 # http://teapot.activestate.com]
Resolving Tcl 8.4 -is package ... [package Tcl 8.6.1 _ ... Installed outside repository, probing dependencies]
Retrieving package Expect 5.43.2 win32-ix86 ...# http://teapot.activestate.com ...
Ok
Installing into C:/app/Tcl/lib/teapot
Installing package Expect 5.43.2 win32-ix86
%

Any Monit like equivalents for windows OS? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 6 years ago.
Improve this question
I've seen the question asked "can you run Monit on Windows?", and unless you want to use a VM, the answer appears to be no.
So...are there any small footprint monit-like applications actually for Windows OS's? What I'm looking for is not only monitoring (of which there are hundreds of apps), but also the ability to execute a script or restart a service. For example, monitor a web page, and restart Tomcat if that page becomes unresponsive (can't just watch the service, because the service is still running but not responding properly).
This is for a small application, not a large application, so the heavyweight/expensive solutions aren't desired.
I didn't find anything out there that fit my needs, so I learned a little Powershell scripting and rolled a solution that should be useful to others as well. Assuming a Windows platform (otherwise use monit!), Powershell is really powerful and easy.
sample-monitor.ps1 script:
$webClient = new-object System.Net.WebClient
###################################################
# BEGIN USER-EDITABLE VARIABLES
# the URL to ping
$HeartbeatUrl = "http://someplace.com/somepage/"
# the response string to look for that indicates things are working ok
$SuccessResponseString = "Some Text"
# the name of the windows service to restart (the service name, not the display name)
$ServiceName = "Tomcat6"
# the log file used for monitoring output
$LogFile = "c:\temp\heartbeat.log"
# used to indicate that the service has failed since the last time we checked.
$FailureLogFile = "c:\temp\failure.log"
# END USER-EDITABLE VARIABLES
###################################################
# create the log file if it doesn't already exist.
if (!(Test-Path $LogFile)) {
New-Item $LogFile -type file
}
$startTime = get-date
$output = $webClient.DownloadString($HeartbeatUrl)
$endTime = get-date
if ($output -like "*" + $SuccessResponseString + "*") {
# uncomment the below line if you want positive confirmation
#"Success`t`t" + $startTime.DateTime + "`t`t" + ($endTime - $startTime).TotalSeconds + " seconds" >> $LogFile
# remove the FailureLog if it exists to indicate we're in good shape.
if (Test-Path $FailureLogFile) {
Remove-Item $FailureLogFile
}
}
else {
"Fail`t`t" + $startTime.DateTime + "`t`t" + ($endTime - $startTime).TotalSeconds + " seconds" >> $LogFile
# restart the service if this is the first time it's failed since the last successful check.
if (!(Test-Path $FailureLogFile)) {
New-Item $FailureLogFile -type file
"Initial failure:" + $startTime.DateTime >> $FailureLogFile
Restart-Service $ServiceName
}
}
The only logic in this script is that it will only try to restart the service once after an initial failure. This is to prevent a situation where a service takes a while to restart, and while it's restarting, the monitor keeps seeing the failure and restarts again (bad infinite loop). Otherwise you can do just about anything, like add email notifications, or do more than just restart a service.
This script will execute once, which means you'll need to control its repetition externally. You could put it in an infinite loop right in the script, but that seems a little flaky. I used windows Task Scheduler, executing it like so:
Program: Powershell.exe
arguments: -command "C:\projects\foo\scripts\monitor.ps1" -noprofile
Start In: C:\projects\foo\scripts
You could also use a more robust scheduler like VisualCron, plug it into a windows service, or via an application server scheduler like Quart.NET. In my case the task scheduler works fine.
I am using ipsentry from RGE Inc (http://www.ipsentry.com/).
Have been using it for several years, saved me many many times.
No affiliation with them, this is not an advertisement, just info from a satisfied customer.
I adjusted a little the Dan Tanner script when he could not connect, showed an error and did not restart the service
$webClient = new-object System.Net.WebClient
###################################################
# BEGIN USER-EDITABLE VARIABLES
# the URL to ping
$HeartbeatUrl = "http://localhost:8080/"
# the response string to look for that indicates things are working ok
$SuccessResponseString = "Apache"
# the name of the windows service to restart (the service name, not the display name)
$ServiceName = "Tomcat6"
# the log file used for monitoring output
$LogFile = "c:\temp\log.log"
# used to indicate that the service has failed since the last time we checked.
$FailureLogFile = "c:\temp\log2.log"
# END USER-EDITABLE VARIABLES
###################################################
# create the log file if it doesn't already exist.
if (!(Test-Path $LogFile)) {
New-Item $LogFile -type file
}
$startTime = get-date
try {
$output = $webClient.DownloadString($HeartbeatUrl)
$endTime = get-date
if ($output -like "*" + $SuccessResponseString + "*") {
# uncomment the below line if you want positive confirmation
#"Success`t`t" + $startTime.DateTime + "`t`t" + ($endTime - $startTime).TotalSeconds + " seconds" >> $LogFile
# remove the FailureLog if it exists to indicate we're in good shape.
if (Test-Path $FailureLogFile) {
Remove-Item $FailureLogFile
}
}
else {
"Fail`t`t" + $startTime.DateTime + "`t`t" + ($endTime - $startTime).TotalSeconds + " seconds" >> $LogFile
# restart the service if this is the first time it's failed since the last successful check.
if (!(Test-Path $FailureLogFile)) {
New-Item $FailureLogFile -type file
"Initial failure:" + $startTime.DateTime >> $FailureLogFile
Restart-Service $ServiceName
}
}
}catch [Net.WebException] {
New-Item $FailureLogFile -type file
"Initial failure:" + $startTime.DateTime + $_.Exception.ToString() >> $FailureLogFile
Restart-Service $ServiceName
}
This can be at least partially accomplished using the Service Control Manager that ship with Windows. It monitors service applications and can automatically start them at boot, restart them when it crashes, etc. Writing your application as a service is one option, but if you can't write the application as a service then you can try to wrap the process using srvany.exe in the Windows Resource Kit.
More info about writing a service: https://support.microsoft.com/en-us/kb/137890
As for the actual monitoring features, I'm not entirely sure what's available, or the extend of SCM's capabilities.

Resources