Powershell script to map to network drive and download files - networking

I am a newbie to powershell. I want to write a script to do the following
Check if I have mapped to a network drive
If not, map to it
Once mapped, check the files in 4 folders at a path on the network drive
If the files are newer to those I compare to on a local drive, copy them ie. only copy new/updated files
Any help with this would be great as I need a starting position to take on this.

You can use net use to determine if the drive is mapped or not:
net use s:
if ($LastExitCode -ne 0)
{
net use s: \\server\share
}
$folders = #{local = 'c:\path1';remote='s:\path1'},
#{local = 'c:\path2';remote='s:\path2'}
$folders | Foreach {xcopy $_.remote $_.local /E /C /H /R /Y /D /I}
Don't forget the existing console tools tend to work just fine in PowerShell and sometimes are the easiest way to get the job done.

Related

Set working directory to mapped network drive in BATCH mode

I'm having issues on windows with R failing when changing the working directory to a mapped network drive (e.g. \Share\Folder mapped to Z:) in batch mode. If I run the same script in an interactive console I don't have any issues. I am accomplishing this by running R.exe with the script specified inside of a windows batch (.bat) file. The .bat file contains the following.
"C:\RRO\R-3.2.1\bin\R.exe" CMD BATCH "C:/Scripts/Rscript.R"
The error is simply...
> setwd( 'Z:/' )
Error in setwd("Z:/") : cannot change working directory
I'd be open to a different approach entirely for scheduling these scripts via the windows task scheduler if that helps avoid the issue. The reason for mapping the drive is that I need to supply some credentials in order to access it, which is done automatically when it is mapped, but can test to see if that's not the case in R if anyone knows how.
I hope this can help with your question.
I duplicated the problem with no errors by using Rscript command instead of a CMD BATCH
my R code which I saved as a script (test1.R)
library(openxlsx)
setwd("P:/Records/Indexing Operations/Indexing Data Analysis/Daily Reports")
my.data = read.xlsx("FSI Daily Project Status Report - 18 Mar 2016.xlsx", sheet = 1)
setwd("C:/Users/golieth/Documents/")
png(filename = "test.png", width = 500, height = 350 )
plot(my.data$Total.Images, my.data$Completed.Images.A,
main = Sys.time())
dev.off()
Note I change the directory 2 times in this file. Once to access data on a mapped network drive and a 2nd to save the image to the computer. I put a timestamp of the current time as the main plot title so you can run the batch file repeatedly and verify it works
my batch file
cd C:\Program Files\R\R-3.2.3\bin\i386
Rscript C:\Users\golieth\Documents\test1.R
Note: On the batch file if your code relies on 32 bit you need to change the directory of your R program (cd) to the R 32bit program. Same with R64. Next the Rscript should reference where you have saved your .R file
Finally, and this might be stating the obvious but make sure you are connected to your VPN before running the batch file.
Imagine a batch file with
cd Z:\<Destination>
Z:
RScript "C:/Scripts/Rscript.R"
This will enable Windows to change to the directory with all credentials and then start R within that directory. So the working dir. is the location from where R is started. Doing so requires that "C:\RRO\R-3.2.1\bin\" is part of your PATH variable.
Good luck!
When writing a .bat file, remember that cd is not used to change drive letters. To change drive letters you simply enter the name of the drive letter, which should be done prior to issuing the final cd to the working directory.
Like this:
sample.bat
z:
cd z:\your\working\directory\
C:\RRO\R-3.2.1\bin\Rscript.exe C:/Scripts/Rscript.R
You can save the files locally in your code, and use file.copy in your code to copy the files over to your network drive. Also try replacing the path in file.copy the network drive letter by the full network address name eg. \\....\.....\

If directory contains exe or msi file, start it with command line arguments

This app is intended for use on Windows only. It is to be built in QT Creator. I'm using 7zip.exe as an example as it is very quick and easy to test with.
I have a list of directories, each one contains a single *.exe or *.msi file.
On pushbutton_clicked() within Qt I want to go to the single directory that I specify and start whichever executable or *.msi file is in that directory. The *.exe or *.msi filename will change from time to time otherwise I could simple use the system command.
system ("start 7zip\7zip.exe /S");
My trouble has been the fact that I want to run a wildcard e.g. *.exe or *.msi and add a command line switch to it.
I now want to execute the single file in path and add the argument /S
I had this working in a batch file:
for /F %%a in ('dir /b 7zip\*.exe') do SET app1=%%~na
%app1% /S
but am unsure how to implement it in Qt.
Thanks
You want to use 2 things: QDirIterator to iterate directories in the system and QProcess to launch the external process with arguments.
Thanks AlexanderVX
They were just what was needed. I'm sure there are many ways to make this more elegant but it does exactly what i want it to do now.
void MainWindow::on_pushButton_clicked()
{
//set initial directory to search for the exe file
QDirIterator file("7zip", QDirIterator::Subdirectories);
while (file.hasNext())
{
file.next();
QString prog = file.fileName(); //get actual filename
QStringList cswitch;
cswitch << "/S"; //create the command switch to use when running the exe
QProcess *install = new QProcess(this); // create new process called install
QDir::setCurrent("7zip"); //set working directory needed to install the exe
install->start(prog, cswitch); //launch the exe with the desired command switch
}
}

Add downloadable executable to website

I have a website project, and an outlook addin that communicates via a webservice to the same database. I'd like to add the outlook addin as "downloadable file" to the interface of the website.
How to achieve that at build time the outlook addin installer ends up in the website's "Download" folder?
Is that possible?
Thanks in advance!
I am not sure this is really a good idea, because maybe not every time you build it it is ok to upload it (broken builds? untested bugs?), but anyway, the idea might be this:
find a way to mount the FTP site mounted as disk Z in the computer and keep it there
you probably want to zip it before, so find and install a command line zip.exe
find a way to have an automated job start every few minutes (like a batch file)
The job (might be a batch file) should do this:
check the file creation date of C:\build\folder\executable.exe and compare it with the file creation date of Z:\download\folder\executable.zip
only if newer, zip C:\build\folder\executable.exe to C:\build\folder\executable.zip and copy C:\build\folder\executable.zip to Z:\download\folder\executable.zip
In what language you write the script is your choice, a windows batch could do (the XCOPY command can copy only newer files), I know PHP and probably would use that with a batch file calling "php my_php_task.php", but you can launch any language interpreter you like.
UPDATE
For zipping you can download this:
http://www.info-zip.org/Zip.html
For copying only newer files u can use XCOPY with options /D (newer only) and /Y (confirm overwriting). Other options here:
http://www.computerhope.com/xcopyhlp.htm
So the batch file might look just similar to these two lines:
zip -f C:\build\folder\executable.zip C:\build\folder\executable.exe
xcopy /D /Y C:\build\folder\executable.zip Z:\download\folder\executable.zip
Have it called every 30 seconds and the job is done. The -f option in zip and /D option in xcopy make sure the script does nothing except check creation dates if you have not recently rebuilt the file.

Which all processes are using shared library

I have a shared library(.so file) on UNIX.
I need to know what all running processes are using it.
Do unix provide any such utility/command?
You can inspect the contents of /proc/<pid>/maps to see which files are mapped into each process. You'll have to inspect every process, but that's easier than it sounds:
$ grep -l /lib/libnss_files-2.11.1.so /proc/*/maps
/proc/15620/maps
/proc/22439/maps
/proc/22682/maps
/proc/32057/maps
This only works on the Linux /proc filesystem, AFAIK.
A quick solution would be to use the lsof command
[root#host]# lsof /lib/libattr.so.1
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
gdm-binar 11442 root mem REG 8,6 30899 295010 /lib/libattr.so.1.1.0
gdm-binar 12195 root mem REG 8,6 30899 295010 /lib/libattr.so.1.1.0
This should work not only for .so files but any other files, dirs, mount points, etc.
N.B. lsof displays all processes that use a file, so there is a very remote possibility of a false positive if is a process that opens the *.so file but not actually use it. If this is an issue for you, then Marcelo's answer would be the way to go.
Do in all directories of interest
ldd * >ldd_output
vi ldd_output
Then look for the the library name, e.g. “aLib.so”. This shows all modules linked to e.g. "aLib.so"

How to programmatically move files into a WebDAV directory

I would like to programmatically move a group of files from a local directory into a WebDAV directory.
I am guessing a simple batch file would not work because it is a WebDAV directory. Note: the machine is Windows Server 2003 so there is no support for mapping a WebDAV directory to a drive letter so the drive just looks like this: http://dev1:8080/data/xml and cannot be made to look like //dev1/data/xml
you could use the BMOVE Method
You could use a webdav client such as the one contained in this project (it's Apache Licensed afaik), then basically call it with a batch file / shell script
Cadaver may allow you to write a batch script that does all this; otherwise you could use CURL directly, but you'd need to know a bit more about the actual WebDAV protocol (you'd basically need to locally traverse a directory, MKCOL for every subdirectory and PUT for every file).
I'm not sure how well either of these tools compile on Windows, but if it doesn't work out of the box, you could always run it on top of Cygwin. While you're using Cygwin, you can also just create standard shell scripts (/bin/sh or /bin/bash) which will likely actually be easier than windows' .BAT format.
You can use python-webdav-library
from webdav import WebdavClient
url = 'https://somesite.net'
mydav = WebdavClient.CollectionStorer(url, validateResourceNames=False)
mydav.connection.addBasicAuthorization(<username>, <password>)
fid = open(<filepath of file you want to upload> ,'rb')
mydav.path = <path to where you want the file to be, ie '/a/b/c.txt'>
mydav.uploadFile(fid)
Free WinSCP (for Windows) supports WebDAV (and WebDAVS). WinSCP supports scripting/command-line operations too.
A sample WinSCP script to upload file over WebDAV:
open http://user#webdav.example.com/
put file.txt /path/
close
Save the script to a file (e.g. script.txt) and run it like:
winscp.com /script=script.txt
You can also put everything on a single line:
winscp.com /command "open http://user#webdav.example.com/" ^
"put file.txt /path/" "close"
If you really want to move (not copy) the files, add the -delete switch to the put command:
put -delete file.txt /path/
See an introduction to scripting with WinSCP.
(I'm the author of WinSCP)
Try the below code.
$filename = 'testing.text';
exec('curl --digest --user "' . $username . ':' . $password . '" -T "' .
$filename . '" "https://sandbox.test.com/dav/content/" ');

Resources