Move file to mapped network drive with MID Server Script Include

greg54
Tera Expert

Hello,

We have a MID Server Script Include running that generates a text file. I am trying to move the generated file (via code) to a network drive that is mapped from the Windows machine the MID Server is running on after it is created. I was able to move the file to a different directory locally using the Java File object, but when I put a UNC path in as the destination directory, I am receiving a "java.io.IOException: Access is denied" error.

I am able to create/update a file in the mapped drive manually, so I know it isn't really a permission issue, but something about doing it via code, it doesn't like.

Does anybody have any advice to point me in the right direction?

Much appreciated!

8 REPLIES 8

Hi Marc,

I did manage to create such functionality, but its a bit tricky...
First of all, I'm exporting the attachment to a folder on the Mid server, because directly exporting it to the wanted network drive took to long and crashed the action most of the times.
Second, if a file is larger then 3-5Mb the copy action also doesn't work.
But most files (when nicely compressed) aren't that large so its fine (and I created an error message for the user when it fails to copy).

So here is the script include code:

createFiles: function () {
var result = this.newItem('result');
var Id = this.getParameter('sysparm_id');
var fileName = '';
var serverPath = '\\\\servername\\sharename$\\folder1\\folder2\\folder3';

//fileName = some value from table, make sure to filter out below characters
fileName = fileName.toString().replace(/[(?!/|\\|:|\*|\?|"|<|>|\|)]+/g, "");
fileName = fileName.toString().replace(/\]+/g,')').replace(/\[+/g,'(');

var gr = new GlideRecord('sys_attachment');
		gr.addQuery('table_sys_id', Id);
		gr.addQuery('table_name','source_table');
		gr.query();
		if (gr.next()) {
			var fileparts = gr.file_name.split('.');
			var ext = fileparts[fileparts.length-1];
			//var ext = gr.file_name.split('.')[1];
			fileName += '.' + ext;
			var sa = new GlideSysAttachment();
			var binData = sa.getBytes(gr); //Get attachment
			var encData = GlideStringUtil.base64Encode(binData); //encode attachment 

			var ftpFilePath = "D:\\Output\\Files\\";   // file path on mid server where file will be copied to.
			
			var server_probe = "";
			
			var gr_sta = new GlideRecord('sys_status');
			gr_sta.addQuery('name', 'glide.db.name');
			gr_sta.query();
			if (gr_sta.next()) {
				if (gr_sta.value.indexOf('test') > -1 ) {
					server_probe = "MID server TEST";	
				}
				else if (gr_sta.value.indexOf('dev') > -1) {
					server_probe = "MID server DEV";
				}
				else {
					server_probe = "MID server PROD";
				}
			}
			try {
				var jspr = new JavascriptProbe(server_probe);   // Creates a dynamic probe for the mid server specified in quotes.
				//gs.log('Begin create file probe');
				jspr.setName('FileToMidServer');   //This is a arbitrary name for the dynamic probe
				jspr.setJavascript("var ddr = new AttachmentSender(); res= ddr.execute();"); //this is the script the probe must run. In this case it calls a mid server script include.
				jspr.addParameter("targetFileName",fileName);
				jspr.addParameter("encodedData",encData);
				jspr.addParameter("targetPath",ftpFilePath);
				jspr.create();
			}
			catch(e) {
				gs.log('Exception downloading attachment: ' + e);
				}
			
			try {
				var wf = new Workflow();
				var workflowId = '6c75df3fdb9913041eb9fbd5ae961982'; // Move File
				var vars = {};
				vars.u_input_target_path = serverPath;
				vars.u_input_file_name = fileName;
				vars.u_input_temp_path = ftpFilePath;
				wf.startFlow(workflowId, emqugr, 'insert', vars);
			}	
			catch(e) {
				gs.log('Exception in workflow Move File: ' + e);
			}
result.setAttribute('answer', fileName);
}

There you see I'm starting a workflow to actually move the file:
find_real_file.png

The run script with the cursor on it does this:

var input_file_name = workflow.inputs.u_input_file_name;
var input_temp_path = workflow.inputs.u_input_temp_path;
//Check mainpath exists
workflow.scratchpad.test_script = 'if(!(Test-Path -Path "' + workflow.scratchpad.target_path + '")) { ' +
	//Create mainpath
	'New-Item -Path "' + workflow.scratchpad.target_path + '" -ItemType directory -Force > $null } ';
//Check if file already exists
workflow.scratchpad.exists_script = 'if ((Test-Path -Path "' + workflow.scratchpad.target_path + '\\' + input_file_name + '")) { ' +
	//Check if Archive folder already exists
	'if (!(Test-Path -Path "' + workflow.scratchpad.target_path + '\\Archive'+ '")) { ' +
		//Create Archive folder
		'New-Item -Path "' + workflow.scratchpad.target_path + '\\Archive' + '" -ItemType directory -Force > $null } ' +
	//Move existing file to Archive
	'Move-Item -Path "' +  workflow.scratchpad.target_path + '\\' + input_file_name + '" -Destination "' + workflow.scratchpad.target_path + '\\Archive' + '" -force }';
//Move new file to mainpath	
workflow.scratchpad.move_script = 'Move-Item -Path "' + input_temp_path + input_file_name + '" -Destination "' + workflow.scratchpad.target_path + '" -Force';
workflow.scratchpad.reloop = 0;

Followed by the Run Powershell (command field):

try { 
#[IO.File]::OpenWrite("&'${workflow.inputs.u_input_temp_path}${workflow.inputs.u_input_file_name}'").close();
${workflow.scratchpad.test_script};
${workflow.scratchpad.exists_script};
${workflow.scratchpad.move_script};
$output = "True"
#Write-Output "%output%" 
Write-Output "$($output)"
#Write-Outpit "%%"

 }
catch { 
$output = "False"
#Write-Output "%%output%%" 
Write-Output "$($output)"
#Write-Output "%%"
 } 

And the following line in the Sensor script of the Run Powershell:

workflow.scratchpad.movesuccess = trim(activity.output);

 

Like I said, not that easy, but it works for me!

Ow this is not exactly a Mid server script include like the title of the topic says...
Ah never mind, perhaps this can still help you 😉

Community Alums
Not applicable

I ended up cheating, we gave the mid server account write access to the directories, made a batch file that copies the files, the batch file is executed by a scheduled task set to run as the mid server user account.

It's not cheating if you don't get caught 😄

j/k nice workaround!