title: IO.Filestream upload file individual file errors with invalid characters from the path
body: <p>I have a problem with a bulk upload script I am working on to upload multiple files with metadata, referenced in a CSV, to SharePoint 2013. </p>
  
  <p>My script runs fine until the <code>Upload()</code> function is called and then errors at the point where the <code>IO.StreamFile</code> opens the file with the error "invalid characters". This is because (I believe) the <code>StreamFile</code> just wants the document name, but I am passing the entire file path and name.</p>
  
  <p>I am stuck as to how to get the <code>StreamFile</code> to recognize the file and continue to upload it from its dir path, as each document will reside in a different directory and be uploaded to a different library. I have simplified the code below.</p>
  
  <pre class="lang-cs prettyprint-override"><code>Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
  Add-Type -Path ([System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client").Location)
  Add-Type -Path ([System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.runtime").Location)
  
  function UploadFile($DestinationFolder, $doc) {
      #Get the datastream of the file, assign it to a variable
      $FileStream = New-Object IO.FileStream($doc.FullName,[System.IO.FileMode]::Open)
      #Create an instance of a FileCreationInformation object
      $FileCreationInfo = New-Object Microsoft.SharePoint.Client.FileCreationInformation
      #Indicate whether or not you would like to overwrite files in the event of a conflict
      $FileCreationInfo.Overwrite = $True
      #Make the datastream of the file you wish to create equal to the datastream of the source file 
      $FileCreationInfo.ContentStream = $FileStream 
      #Make the URL of the file equal to the $File variable which was passed to the function.  This will be equal to the source file name
      $FileCreationInfo.url = $doc
      #Add the file to the destination folder which was passed to the function, using the FileCreationInformation supplied.  Assign this to a variable so that it can be loaded into context.
      $Upload = $DestinationFolder.Files.Add($FileCreationInfo)
      #Set metadata properties
      $listItem = $Upload.ListItemAllFields
      #Adds member number as meta data in the library against the file
      $listItem["MemberNumber"] = $MemberNumber
      $listItem.Update()
      $Context.Load($Upload)
      $Context.ExecuteQuery()
  }
  
  $GroupSite= "http://Contoso:1985/sites/group1"
  $UserName = "contoso/admin"
  $Password = "Password"
  $Context = New-Object Microsoft.SharePoint.Client.ClientContext($GroupSite)
  $Creds = New-Object System.Net.NetworkCredential($UserName, (ConvertTo-SecureString $Password -AsPlainText -Force))
  $Context.Credentials = $Creds
  
  $src = "D:\Import\CSVs\group1.csv"
  $reader = New-Object IO.StreamReader($src)
  $header = Get-Content -Path $src | select -First 1
  while (($line = $reader.ReadLine()) -ne $null) {
      #Set metadata
      $data = $line -split ','
      $PersonID = $data[14]
      #This is the column in the CSV that gives the file directory path to the file
      $File = $data[17]
      $FileName = $File .Substring($File .LastIndexOf("\")+1)
      $FileExists = Test-Path $File
      # if document doesnt exist log it:
      if ($FileExists -eq $false) {
          Write-Host "$FileName Document Doesnt Exist!" -ForegroundColor Green
      } else {
          $MemberNumber = $data[0]
          $List = $Context.Web.Lists.GetByTitle($PersonID)
          $Context.Load($List)
          $Context.ExecuteQuery()
          #Get the document/file  
          $ActualFile = Get-Item -Path $File
          foreach ($doc in ($ActualFile)) {
              Write-Host "Uploading file " $doc.Name "to" $PersonID -ForegroundColor Cyan
              UploadFile($list.RootFolder) $doc
          }
      }
  }
  </code></pre>