2

I created az Azure file share where I would like to store a few SharePoint provisioning files, templates and xml's. Files are copied to the share and ready to use.

I am aware of the Get-AzureStorageFileContent command that can be used to retrieve single files, but I need to see this share as share, as the files are referenced from withing the the PnP provisioning template like:

  <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="webparts\head.xml"/>

This works fine when I run the script local or from network share. So, my question is, how can I either use the UNC path or map it as network drive?

According to the documentation, I should be able to use it as smb share, but when I try to connect, I get this error:

New-SmbMapping : Cannot connect to CIM server. The specified service does not exist as an installed service.

New-PSDrive doesn't exist in Azure Powershell. I found this as a module in Azure, but I stopped installing dependencies when one of them required to update .Net in Azure.

Can someone please give me an end-to-end guide, how can I achieve a real file share functionality with Azure File Share?

Edit: and acceptable workaround would be if I could copy all files from the share to current temporary folder, because from there I could access them with $env:TEMP .

5
  • As per my understanding, in the runbook, you want to access the fileshare via UNC path? or copy all the files from fileshare to $env:temp? If I'm misunderstanding, please correct me. Commented Jan 10, 2019 at 5:39
  • Yes. If possible, I would like that all functions in the runbook could use the share as they would use a normal network share. If this is not possible, then I would like to copy everything to temp and work from there. Commented Jan 10, 2019 at 7:37
  • Does the file share contains directories, or just contains files? Commented Jan 10, 2019 at 7:58
  • Both files and folders. Commented Jan 10, 2019 at 8:27
  • Ok, I will update my answer later. Commented Jan 10, 2019 at 8:30

2 Answers 2

3

Update: recursively copy all the files and folders to $env:temp

Code in the powershell runbook:

function Get-AzureFiles
{
param([string]$filesharename = 'testfolder', #replace with your own fileshare name
      [string]$username = 'your account name',
      [string]$password = 'your account key', 
      [string]$destination=$env:TEMP+"\", #note there is a slash at the end
      [string]$path="")

      $temp = $env:TEMP

      # get the context
      $context = New-AzureStorageContext -StorageAccountName $username -StorageAccountKey $password

      # get all files and directories
      if($path -eq "")
      {
      $content = Get-AzureStorageFile -ShareName $filesharename -Context $context
      }
      else
      {
      $content = Get-AzureStorageFile -ShareName $filesharename -Context $context -Path $path | Get-AzureStorageFile
      }

      if(!(test-path $destination))
        {
        mkdir $destination
        }

      foreach($c in $content)
      {
        $p = $c.uri.LocalPath -replace "$($c.share.name)/" ,''
        #write-host "the value p is: $p"

        #if it's a directory in fileshare
        if($c.gettype().name -eq "CloudFileDirectory")
        {
           # Write-Host "$($c.share.name) is a directory"
            $destination =$temp + $c.uri.PathAndQuery -replace "/","\"

            #create the folder locally
            if(!(test-path $destination))
            {
            mkdir $destination
            #write-host "the new directory $destination is created locally."
            }

            #define the folder path in fileshare
            $path = ($c.uri.localpath -replace "/$filesharename/" , "") -replace "/","\"

            Get-AzureFiles -destination $destination -path $path

        }
        #if it's a file
        elseif($c.gettype().name -eq "CloudFile")
        {         
         $s = $temp + $c.uri.PathAndQuery -replace "/","\"
         #Write-Output "downloading --- $s"

         $d1 = $c.uri.PathAndQuery -replace "/","\"
         $d1 = $d1.remove($d1.LastIndexOf("\")+1)

         $destination =$temp + $d1



            #create the folder locally
            if(!(test-path $destination))
            {
            mkdir $destination
            #write-host "the new directory $destination is created locally."
            }
         $path_temp = $c.uri.PathAndQuery -replace "/$filesharename/",""

         Get-AzureStorageFileContent -ShareName $filesharename -Path $path_temp  -Destination $destination -Context $context        
        }
      }
}


function do-test
{
get-AzureFiles

# you can operate the files copied to $env:temp
dir $env:TEMP\testfolder
dir $env:TEMP\testfolder\t1
dir $env:TEMP\testfolder\t1\t1sub
}

do-test

Test result:

enter image description here

My fileshare structure in azure portal:

enter image description here

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks, this works good with files in the root. Is there any chance to get everything, files, folder recursively?
I'm working on this, and will let you know when any updates :)
@vilmarci, I have updated my answer, recursively copy all the files and folders in fileshare. If it works for you, please help mark it as an answer. Thanks:)
Thank you for helping. The folders are created, but no files (except the ones in the root) are copied. I see an error message after every folder: ERROR: New-AzureStorageContext : Invalid length for a Base-64 char array or string. I enabled the outputs in your code, I never see the the "downloading ..." part.
Found it: in this line Get-AzureFiles -destination $destination -path $path you also need to pass the context and the file share name. Also, it has difficulties, when the path contains spaces and encoded to %20, these should be decoded, but I can manage that from this point. Otherwise it is perfect, thank you very much.
0

It looks like the error you received is related to permissions on the DNS server, this Thread provides the below solution:

add these two roles: DnsAdmins and WinRMRemoteWMIUsers__ on the DNS Server/DC. then the following on the DNS server:

*1. Open Computer Management Console. Right click WMI Control (under Services and Applications) and click property. 2. In the newly open Window, click on Security tab.

  1. Expand Root tree, and then click on the node CIMV2, and click the button security
  2. In the newly open Window, click the button Advanced.
  3. In the newly open Window, click the button Add under the permission tab.
  4. In the newly open Window, click on “select a principal”, then search and add the group WinRMRemoteWMIUsers__ as the principal, then click ok.
  5. In the applies to, choose “this namespace and subnamespace”.
  6. For the permission, check on “Execute Methods”, “Enable Accounts” and “Remote Enable”
  7. Click OK three times.
  8. Then navigate to the node Root – Microsoft – Windows – DNS. Do the same things, add permission for WinRMRemoteWMIUsers.
  9. Restart service “Windows Management Instrumentation.
  10. Check whether the issue is fixed.*

This is the full MS official documentation which provides steps to attach a drive locally as well

1 Comment

This is a ps runbook in Azure, not local.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.