internal IEnumerator<DSResource> InvokeCmdletAsync(System.Management.Automation.PowerShell powerShell, Expression expression, EventHandler<DataAddedEventArgs> dataAddedEventHandler, AsyncCallback executionCompletionCallback, bool noStreamingResponse) { Tracer tracer = new Tracer(); this.dataStore = new AsyncDataStore<DSResource>(expression, noStreamingResponse); this.output = new PSDataCollection<PSObject>(); tracer.CommandInvocationStart(this.cmdletInfo.CmdletName); powerShell.Runspace = this.runspace.Item.Runspace; powerShell.AddCommand(this.cmdletInfo.CmdletName); foreach (string key in this.parameters.Keys) { if (!this.cmdletInfo.IsSwitch(key)) { powerShell.AddParameter(key, this.parameters[key]); } else { powerShell.AddParameter(key); } } this.isExecutionCompleted = false; using (OperationTracer operationTracer = new OperationTracer(new Action<string>(TraceHelper.Current.CmdletExecutionStart), new Action<string>(TraceHelper.Current.CmdletExecutionEnd), powerShell.Commands.ToTraceMessage())) { try { this.timer.Start(); powerShell.Invoke<PSObject>(null, this.output, Utils.GetPSInvocationSettings()); } catch (CommandNotFoundException commandNotFoundException1) { CommandNotFoundException commandNotFoundException = commandNotFoundException1; throw new CommandInvocationFailedException(powerShell.Commands.Commands[0].CommandText, commandNotFoundException); } catch (ParameterBindingException parameterBindingException1) { ParameterBindingException parameterBindingException = parameterBindingException1; throw new CommandInvocationFailedException(powerShell.Commands.Commands[0].CommandText, parameterBindingException); } catch (CmdletInvocationException cmdletInvocationException1) { CmdletInvocationException cmdletInvocationException = cmdletInvocationException1; throw new CommandInvocationFailedException(powerShell.Commands.Commands[0].CommandText, cmdletInvocationException); } } return new BlockingEnumerator<DSResource>(this.dataStore); }
} // PerformCopyFileToRemoteSession private bool RemoteDestinationPathIsFile(string destination, System.Management.Automation.PowerShell ps) { ps.AddCommand(CopyFileRemoteUtils.PSCopyToSessionHelperName); ps.AddParameter("isFilePath", destination); Hashtable op = SafeInvokeCommand.Invoke(ps, this, null); if (op == null || op["IsFileInfo"] == null) { Exception e = new IOException(String.Format( CultureInfo.InvariantCulture, FileSystemProviderStrings.CopyItemRemotelyFailedToValidateIfDestinationIsFile, destination)); WriteError(new ErrorRecord(e, "CopyError", ErrorCategory.WriteError, destination)); return false; } return (bool)(op["IsFileInfo"]); }
private string CreateDirectoryOnRemoteSession(string destination, bool force, System.Management.Automation.PowerShell ps) { ps.AddCommand(CopyFileRemoteUtils.PSCopyToSessionHelperName); ps.AddParameter("createDirectoryPath", destination); if (force) { ps.AddParameter("force", true); } Hashtable op = SafeInvokeCommand.Invoke(ps, this, null); // If op == null, SafeInvokeCommand.Invoke throwns an error. if (op["ExceptionThrown"] != null) { // If an error is thrown on the remote session, it is written via SafeInvokeCommand.Invoke. if ((bool)op["ExceptionThrown"]) return null; } if (force && (op["DirectoryPath"] == null)) { Exception e = new IOException(String.Format(CultureInfo.InvariantCulture, FileSystemProviderStrings.CopyItemRemotelyFailedToCreateDirectory, destination)); WriteError(new ErrorRecord(e, "FailedToCreateDirectory", ErrorCategory.WriteError, destination)); return null; } string path = (String)(op["DirectoryPath"]); if ((!force) && (bool)op["PathExists"]) { Exception e = new IOException(StringUtil.Format(FileSystemProviderStrings.DirectoryExist, path)); WriteError(new ErrorRecord(e, "DirectoryExist", ErrorCategory.ResourceExists, path)); return null; } return path; } // CreateDirectoryOnRemoteSession
private bool CopyFileStreamToRemoteSession(FileInfo file, string destinationPath, System.Management.Automation.PowerShell ps, bool isAlternateStream, string streamName) { string activity = String.Format(CultureInfo.InvariantCulture, FileSystemProviderStrings.CopyItemRemotelyProgressActivity, file.FullName, destinationPath); string statusDescription = String.Format(CultureInfo.InvariantCulture, FileSystemProviderStrings.CopyItemRemotelyStatusDescription, "localhost", ps.Runspace.ConnectionInfo.ComputerName); ProgressRecord progress = new ProgressRecord(0, activity, statusDescription); progress.PercentComplete = 0; progress.RecordType = ProgressRecordType.Processing; WriteProgress(progress); // 4MB gives the best results without spiking the resources on the remote connection. int fragmentSize = FILETRANSFERSIZE; byte[] fragment = null; int iteration = 0; bool success = false; FileStream fStream = null; try { // Main data stream if (!isAlternateStream) { fStream = File.OpenRead(file.FullName); } else { fStream = AlternateDataStreamUtilities.CreateFileStream(file.FullName, streamName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); } long remainingFileSize = fStream.Length; do { if (Stopping) { return false; } iteration++; int toRead = fragmentSize; if (toRead > remainingFileSize) { toRead = (int)remainingFileSize; } if (fragment == null) { fragment = new byte[toRead]; } else if (toRead < fragmentSize) { fragment = new byte[toRead]; } int readSoFar = 0; while (readSoFar < toRead) { readSoFar += fStream.Read(fragment, 0, toRead); } remainingFileSize -= readSoFar; string b64Fragment = System.Convert.ToBase64String(fragment); // Main data stream if (!isAlternateStream) { ps.AddCommand(CopyFileRemoteUtils.PSCopyToSessionHelperName); ps.AddParameter("copyToFilePath", destinationPath); ps.AddParameter("createFile", (iteration == 1)); if ((iteration == 1) && (b64Fragment.Length == 0)) { // This fixes the case in which the user tries to copy an empty file between sessions. // Scenario 1: The user creates an empty file using the Out-File cmdlet. // In this case the file length is 6. // "" | out-file test.txt // Scenario 2: The user generates an empty file using the New-Item cmdlet. // In this case the file length is 0. // New-Item -Path test.txt -Type File // Because of this, when we create the file on the remote session, we need to check // the length of b64Fragment to figure out if we are creating an empty file. ps.AddParameter("emptyFile", true); } else { ps.AddParameter("b64Fragment", b64Fragment); } } else { ps.AddCommand(CopyFileRemoteUtils.PSCopyToSessionHelperName); ps.AddParameter("copyToFilePath", destinationPath); ps.AddParameter("b64Fragment", b64Fragment); ps.AddParameter("streamName", streamName); } Hashtable op = SafeInvokeCommand.Invoke(ps, this, null); if (op == null || op["BytesWritten"] == null) { //write error to stream Exception e = new IOException(String.Format(CultureInfo.InvariantCulture, FileSystemProviderStrings.CopyItemRemotelyFailed, file)); WriteError(new ErrorRecord(e, "CopyError", ErrorCategory.WriteError, file.FullName)); return false; } if ((int)(op["BytesWritten"]) != toRead) { Exception e = new IOException(String.Format(CultureInfo.InvariantCulture, FileSystemProviderStrings.CopyItemRemotelyFailed, file)); WriteError(new ErrorRecord(e, "CopyError", ErrorCategory.WriteError, file.FullName)); return false; } if (fStream.Length > 0) { int percentage = (int)((fStream.Length - remainingFileSize) * 100 / fStream.Length); progress.PercentComplete = percentage; WriteProgress(progress); } } while (remainingFileSize > 0); progress.PercentComplete = 100; progress.RecordType = ProgressRecordType.Completed; WriteProgress(progress); success = true; } catch (IOException ioException) { // IOException takes care of FileNotFoundException, DirectoryNotFoundException, and PathTooLongException WriteError(new ErrorRecord(ioException, "CopyItemRemotelyIOError", ErrorCategory.WriteError, file.FullName)); } catch (ArgumentException argException) { WriteError(new ErrorRecord(argException, "CopyItemRemotelyArgumentError", ErrorCategory.WriteError, file.FullName)); } catch (NotSupportedException notSupportedException) { WriteError(new ErrorRecord(notSupportedException, "CopyFileInfoRemotelyPathRefersToANonFileDevice", ErrorCategory.InvalidArgument, file.FullName)); } catch (SecurityException securityException) { WriteError(new ErrorRecord(securityException, "CopyFileInfoRemotelyUnauthorizedAccessError", ErrorCategory.PermissionDenied, file.FullName)); } finally { if (fStream != null) { fStream.Dispose(); } } return success; }
private void SetRemoteFileMetadata(FileInfo file, string remoteFilePath, System.Management.Automation.PowerShell ps) { Hashtable metadata = GetFileMetadata(file); if (metadata != null) { ps.AddCommand(CopyFileRemoteUtils.PSCopyToSessionHelperName); ps.AddParameter("metaDataFilePath", remoteFilePath); ps.AddParameter("metaDataToSet", metadata); SafeInvokeCommand.Invoke(ps, this, null, false); } }
// Validate that the given remotePath exists, and do the following: // 1) If the remotePath is a FileInfo, then just return the remotePath. // 2) If the remotePath is a DirectoryInfo, then return the remotePath + the given filename. // 3) If the remote path does not exist, but its parent does, and it is a DirectoryInfo, then return the remotePath. // 4) If the remotePath or its parent do not exist, return null. private string MakeRemotePath(System.Management.Automation.PowerShell ps, string remotePath, string filename) { bool isFileInfo = false; bool isDirectoryInfo = false; bool parentIsDirectoryInfo = false; string path = null; ps.AddCommand(CopyFileRemoteUtils.PSCopyToSessionHelperName); ps.AddParameter("remotePath", remotePath); Hashtable op = SafeInvokeCommand.Invoke(ps, this, null); if (op != null) { if (op["IsDirectoryInfo"] != null) { isDirectoryInfo = (bool)op["IsDirectoryInfo"]; } if (op["IsFileInfo"] != null) { isFileInfo = (bool)op["IsFileInfo"]; } if (op["ParentIsDirectoryInfo"] != null) { parentIsDirectoryInfo = (bool)op["ParentIsDirectoryInfo"]; } } if (isFileInfo) { // The destination is a file, so we are going to overwrite it. path = remotePath; } else if (isDirectoryInfo) { // The destination is a directory, so append the file name to the path. path = Path.Combine(remotePath, filename); } else if (parentIsDirectoryInfo) { // At this point we know that the remotePath is neither a file or a directory on the remote target. // However, if the parent of the remotePath exists, then we are doing a copy-item operation in which // the destination file name is already being passed, e.g., // copy-item -path c:\localDir\foo.txt -destination d:\remoteDir\bar.txt -toSession $s // Note that d:\remoteDir is a directory that exists on the remote target machine. path = remotePath; } return path; }
private bool RemoteDirectoryExist(System.Management.Automation.PowerShell ps, string path) { bool pathExists = false; ps.AddCommand(CopyFileRemoteUtils.PSCopyRemoteUtilsName); ps.AddParameter("dirPathExists", path); Hashtable op = SafeInvokeCommand.Invoke(ps, this, null); if (op != null) { if (op["Exists"] != null) pathExists = (bool)op["Exists"]; } return pathExists; }
private bool PerformCopyFileFromRemoteSession(string sourceFileFullName, FileInfo destinationFile, string destinationPath, bool force, System.Management.Automation.PowerShell ps, long fileSize, bool isAlternateDataStream, string streamName) { bool success = false; string activity = String.Format(CultureInfo.InvariantCulture, FileSystemProviderStrings.CopyItemRemotelyProgressActivity, sourceFileFullName, destinationFile.FullName); string statusDescription = String.Format(CultureInfo.InvariantCulture, FileSystemProviderStrings.CopyItemRemotelyStatusDescription, ps.Runspace.ConnectionInfo.ComputerName, "localhost"); ProgressRecord progress = new ProgressRecord(0, activity, statusDescription); progress.PercentComplete = 0; progress.RecordType = ProgressRecordType.Processing; WriteProgress(progress); FileStream wStream = null; bool errorWhileCopyRemoteFile = false; try { // The main data stream if (!isAlternateDataStream) { // If force is specified, and the file already exist at the destination, mask of the readonly, hidden, and system attributes if (force && File.Exists(destinationFile.FullName)) { destinationFile.Attributes = destinationFile.Attributes & ~(FileAttributes.ReadOnly | FileAttributes.Hidden | FileAttributes.System); } wStream = new FileStream(destinationFile.FullName, FileMode.Create); } // an alternate stream else { wStream = AlternateDataStreamUtilities.CreateFileStream(destinationFile.FullName, streamName, FileMode.Append, FileAccess.Write, FileShare.ReadWrite); } long fragmentSize = FILETRANSFERSIZE; long copiedSoFar = 0; long currentIndex = 0; while (true) { ps.AddCommand(CopyFileRemoteUtils.PSCopyFromSessionHelperName); ps.AddParameter("copyFromFilePath", sourceFileFullName); ps.AddParameter("copyFromStart", currentIndex); ps.AddParameter("copyFromNumBytes", fragmentSize); if (force) { ps.AddParameter("force", true); } if (isAlternateDataStream) { ps.AddParameter("isAlternateStream", true); ps.AddParameter("streamName", streamName); } Hashtable op = SafeInvokeCommand.Invoke(ps, this, null); // Check if there was an exception when reading the remote file. if (op == null) { errorWhileCopyRemoteFile = true; Exception e = new IOException(String.Format(CultureInfo.InvariantCulture, FileSystemProviderStrings.CopyItemRemotelyFailedToReadFile, sourceFileFullName)); WriteError(new ErrorRecord(e, "FailedToCopyFileFromRemoteSession", ErrorCategory.WriteError, sourceFileFullName)); break; } if (op["ExceptionThrown"] != null) { bool failedToReadFile = (bool)(op["ExceptionThrown"]); if (failedToReadFile) { // The error is written to the error array via SafeInvokeCommand errorWhileCopyRemoteFile = true; break; } } // To accomodate empty files String content = ""; if (op["b64Fragment"] != null) { content = (String)op["b64Fragment"]; } bool more = (bool)op["moreAvailable"]; currentIndex += fragmentSize; byte[] bytes = System.Convert.FromBase64String(content); wStream.Write(bytes, 0, bytes.Length); copiedSoFar += bytes.Length; if (wStream.Length > 0) { int percentage = (int)(copiedSoFar * 100 / wStream.Length); progress.PercentComplete = percentage; WriteProgress(progress); } if (!more) { success = true; break; } } progress.PercentComplete = 100; progress.RecordType = ProgressRecordType.Completed; WriteProgress(progress); } catch (IOException ioException) { // IOException takes care of FileNotFoundException, DirectoryNotFoundException, and PathTooLongException WriteError(new ErrorRecord(ioException, "CopyItemRemotelyIOError", ErrorCategory.WriteError, sourceFileFullName)); } catch (ArgumentException argException) { WriteError(new ErrorRecord(argException, "CopyItemRemotelyArgumentError", ErrorCategory.WriteError, sourceFileFullName)); } catch (NotSupportedException notSupportedException) { WriteError(new ErrorRecord(notSupportedException, "CopyFileInfoRemotelyPathRefersToANonFileDevice", ErrorCategory.InvalidArgument, sourceFileFullName)); } catch (SecurityException securityException) { WriteError(new ErrorRecord(securityException, "CopyFileInfoRemotelyUnauthorizedAccessError", ErrorCategory.PermissionDenied, sourceFileFullName)); } catch (UnauthorizedAccessException unauthorizedAccessException) { WriteError(new ErrorRecord(unauthorizedAccessException, "CopyFileInfoItemRemotelyUnauthorizedAccessError", ErrorCategory.PermissionDenied, sourceFileFullName)); } finally { if (wStream != null) { wStream.Dispose(); } // If copying the file from the remote session failed, then remove it. if (errorWhileCopyRemoteFile && File.Exists(destinationFile.FullName)) { if (!(destinationFile.Attributes.HasFlag(FileAttributes.ReadOnly) || destinationFile.Attributes.HasFlag(FileAttributes.Hidden) || destinationFile.Attributes.HasFlag(FileAttributes.System))) { RemoveFileSystemItem(destinationFile, true); } } } return success; }
// If the target supports alternate data streams the following must be true: // 1) The remote session must be PowerShell V3 or higher to support Streams // 2) The target drive must be NTFS // private bool RemoteTargetSupportsAlternateStreams(System.Management.Automation.PowerShell ps, string path) { bool supportsAlternateStreams = false; ps.AddCommand(CopyFileRemoteUtils.PSCopyToSessionHelperName); ps.AddParameter("supportAltStreamPath", path); Hashtable op = SafeInvokeCommand.Invoke(ps, this, null); if (op != null && op["TargetSupportsAlternateStreams"] != null) { supportsAlternateStreams = (bool)op["TargetSupportsAlternateStreams"]; } return supportsAlternateStreams; }
} // CopyDirectoryFromRemoteSession private ArrayList GetRemoteSourceAlternateStreams(System.Management.Automation.PowerShell ps, string path) { ArrayList streams = null; bool supportsAlternateStreams = false; ps.AddCommand(CopyFileRemoteUtils.PSCopyFromSessionHelperName); ps.AddParameter("supportAltStreamPath", path); Hashtable op = SafeInvokeCommand.Invoke(ps, this, null); if (op != null && op["SourceSupportsAlternateStreams"] != null) { supportsAlternateStreams = (bool)op["SourceSupportsAlternateStreams"]; } if (supportsAlternateStreams) { PSObject obj = (PSObject)op["Streams"]; streams = (ArrayList)obj.BaseObject; } return streams; }
private Hashtable GetRemoteFileMetadata(string filePath, System.Management.Automation.PowerShell ps) { ps.AddCommand(CopyFileRemoteUtils.PSCopyFromSessionHelperName); ps.AddParameter("getMetaFilePath", filePath); Hashtable metadata = SafeInvokeCommand.Invoke(ps, this, null); return metadata; }
} // CopyFileInfoItem private void CopyDirectoryFromRemoteSession( string sourceDirectoryName, string sourceDirectoryFullName, string destination, bool force, bool recurse, System.Management.Automation.PowerShell ps) { Dbg.Diagnostics.Assert((sourceDirectoryName != null && sourceDirectoryFullName != null), "The caller should verify directory."); if (IsItemContainer(destination)) { destination = MakePath(destination, sourceDirectoryName); } s_tracer.WriteLine("destination = {0}", destination); // Confirm the copy with the user string action = FileSystemProviderStrings.CopyItemActionDirectory; string resource = StringUtil.Format(FileSystemProviderStrings.CopyItemResourceFileTemplate, sourceDirectoryFullName, destination); if (ShouldProcess(resource, action)) { // Create destinationPath directory. This will fail if the directory already exists // and Force is not selected. CreateDirectory(destination, false); // If failed to create directory if (!Utils.NativeDirectoryExists(destination)) { return; } if (recurse) { // Get all the files for that directory from the remote session ps.AddCommand(CopyFileRemoteUtils.PSCopyFromSessionHelperName); ps.AddParameter("getPathDir", sourceDirectoryFullName); Hashtable op = SafeInvokeCommand.Invoke(ps, this, null); if (op == null) { Exception e = new IOException(String.Format( CultureInfo.InvariantCulture, FileSystemProviderStrings.CopyItemRemotelyFailedToGetDirectoryChildItems, sourceDirectoryFullName)); WriteError(new ErrorRecord(e, "CopyError", ErrorCategory.WriteError, sourceDirectoryFullName)); return; } if (op["Files"] != null) { PSObject obj = (PSObject)op["Files"]; ArrayList filesList = (ArrayList)obj.BaseObject; foreach (PSObject fileObject in filesList) { Hashtable file = (Hashtable)fileObject.BaseObject; string fileName = (string)file["FileName"]; string filePath = (string)file["FilePath"]; long fileSize = (long)file["FileSize"]; // Making sure to obey the StopProcessing. if (Stopping) { return; } bool excludeFile = SessionStateUtilities.MatchesAnyWildcardPattern(fileName, _excludeMatcher, defaultValue: false); if (!excludeFile) { // If an exception is thrown in the remote session, it is surface to the user via PowerShell Write-Error. CopyFileFromRemoteSession(fileName, filePath, destination, force, ps, fileSize); } } } // for files if (op["Directories"] != null) { PSObject obj = (PSObject)op["Directories"]; ArrayList directories = (ArrayList)obj.BaseObject; foreach (PSObject dirObject in directories) { Hashtable dir = (Hashtable)dirObject.BaseObject; string dirName = (string)dir["Name"]; string dirFullName = (string)dir["FullName"]; // Making sure to obey the StopProcessing. if (Stopping) { return; } // If an exception is thrown in the remote session, it is surface to the user via PowerShell Write-Error. CopyDirectoryFromRemoteSession(dirName, dirFullName, destination, force, recurse, ps); } } // for directories } } // ShouldProcess } // CopyDirectoryFromRemoteSession
private void GenerateRequestData(System.Net.Http.HttpPostRequestBuilder endpoint) { endpoint.AddParameter("action", "doeditfolder"); ICollection<int> keys = this.FolderTable.Keys; foreach (var key in keys) { string folderName = this.FolderTable[key]; folderName = WebUtility.UrlEncode(folderName); folderName = folderName.Replace("%2b", "+"); string queryString = string.Format("folderlist[{0}]", key); endpoint.AddParameter(WebUtility.UrlEncode(queryString), folderName); } endpoint.AddParameter("highest", this.NewFolderFieldIndex); endpoint.AddParameter("submit", "Edit Folders"); }
public override void Serialize(System.IO.BinaryWriter outStream) { base.Serialize(outStream); outStream.AddParameter(IsMore); outStream.AddParameter(Value); }
// Powershell object passed here will be disposed off by the caller private static MiResult PullOneModule(System.Management.Automation.PowerShell powershell, ModuleSpecification moduleSpecification, string configurationId, string downloadLocation, Hashtable arguments, Collection<PSObject> argumentParameters, out string downloadedModule, out Collection<PSObject> pullOneModuleResult, out ErrorRecord errorRecord, out UInt32 getActionStatusCode) { pullOneModuleResult = null; downloadedModule = null; string moduleVersionString = GetModuleVersionStringFromModuleSpecification(moduleSpecification); try { powershell.AddParameter(ParamModules, moduleSpecification); // Log to ETW Channel:Microsoft-Windows-DSC/Operational S_DscCoreR.EventWriteLCMPullGetModuleAttempt(S_DscCoreR.JobGuidString, _pluginModuleName, configurationId, moduleVersionString); powershell.Streams.Error.Clear(); pullOneModuleResult = arguments.Count > 0 ? powershell.Invoke(argumentParameters) : powershell.Invoke(); if (powershell.Streams.Error.Count > 0) { errorRecord = powershell.Streams.Error[0]; powershell.Dispose(); if( string.Compare(errorRecord.FullyQualifiedErrorId, "WebDownloadManagerUnknownChecksumAlgorithm", StringComparison.OrdinalIgnoreCase) == 0 ) { getActionStatusCode = (int)GetActionStatusCodeTypes.InvalidChecksumAlgorithm; } else { getActionStatusCode = (int)GetActionStatusCodeTypes.GetDscModuleCommandFailure; } return MiResult.FAILED; } } catch (Exception ex) { errorRecord = GetErrorRecord("GetModuleExecutionFailure", ex, ErrorCategory.InvalidType, PSinfrastructureStrings.GetModuleExecutionFailure, _pluginModuleName); getActionStatusCode = (int)GetActionStatusCodeTypes.GetDscModuleCommandFailure; return MiResult.FAILED; } S_DscCoreR.EventWriteLCMPullModuleDownloadLocation(S_DscCoreR.JobGuidString, moduleVersionString, downloadLocation); errorRecord = null; getActionStatusCode = (int)GetActionStatusCodeTypes.Success; return MiResult.OK; }
public override void Serialize(System.IO.BinaryWriter outStream) { base.Serialize(outStream); outStream.AddParameter(ConId); outStream.AddParameter(Exchange); }