Sharing a folder for a specific machine/user using powershell - powershell

I'm trying to share a folder to a specific machine/user using Powershell.
Some background: I've many Windows machines which have a folder (data folders) that needs to be backed up. These folders are shared with a "special" machine running backup software. This software daily checks the contents of the data folders and backup the data to its local harddisks. When a new machine arrives, we share the folder by hand using Explorer. (Properties -> sharing -> share ...). All the machines are part of a large network, and we don't want to share the data with all the machines. Therefore we only allow read access to the data folder by the backup machine (let's call the user on the backup machine domain\BackupUser). I want to move the creation of these shared data folders into some script which we can run from Powershell.
The command I found is: New-SmbShare -Path C:\Data\ -Name Data -ReadAccess "domain\BackupUser". The command will create the (smb) share as expected, and I can observe it via the backup machine. But on access it, the permission is denied.
When listing the shared folder access (Get-SmbShareAccess -Name "Data") it does show the expected user.
I've also tried to create the shared folder with: net share Data=C:\Data /grant:BackupUser,FULL but still got the permission is denied error.
The weird thing is when the folder is shared using explorer and list the access (`Get-SmbShareAccess -Name "Data"). The user (BackupUser) is not listed, but an "Everyone" is shown. But when trying to access the data folder from another (random) machine, it does not give access, as desired. The backup machine does have access.
So, the main question: What powershell command(s) creates a new shared folder to a specific machine/user?

Share permissions are not the same as file system permissions.
Set the SHARE permission, then apply the FOLDER/FILE permissions:
$FolderName = 'C:\Data'
$UserId = 'DOMAIN\BackupUser'
New-SmbShare -Path $FolderName -Name Data -ReadAccess $UserId
$Acl = Get-Acl $FolderName
$NewAccessRule = New-Object system.security.accesscontrol.filesystemaccessrule($UserId,"Read","Allow")
$Acl.SetAccessRule($NewAccessRule)
Set-Acl $FolderName $Acl

Related

Setting network share permissions on subdirectory with PowerShell

I want to setup a network share granting READ only permissions to the root, but READ/WRITE permissions to a sub directory within it.
I can do this manually, but I want to be able to do it using PowerShell.
\\myserver\MyShare (READ access here for user TESTUSER)
\\myserver\MyShare\subfolder (READ/WRITE access here for user TESTUSER)
Manual steps in Windows Explorer - open folder properties dialog, "Sharing" tab, "Share..." button, I can then add my user and set the permissions. I can do this to BOTH the root of the network share and the "subfolder".
The closest thing I have managed in PowerShell is the following, which sets up the root only:
New-SmbShare –Name MyShare –Path e:\MyShare -ReadAccess "Domain\TESTUSER"
However, this seems to do the equivalent of the "Advanced sharing" options that appear on the folder properties dialog, which only apply when setting up a NEW network share, and not to folders WITHIN an existing network share. When I run this script, the TESTUSER isn't added to the list of users in the simple "Share..." dialog so there must be another way of setting up the permissions.
My question: How do I setup permissions using PowerShell in the same way Windows does from the "Share..." button on the folder properties?
I'm using Windows Server 2012 R2.
Share permissions apply to shares as a whole, meaning they affect the shared folder and everything it contains. It's not possible to apply different share permissions to a subfolder without publishing that subfolder as a different share, and even then the modified permissions would only become effective when accessing the subfolder through the new share, not when accessing it as a subfolder of the original share.
For fine-grained access control you MUST use filesystem ACLs. However, if the share is defined as read-only via share permissions, the user will be denied write access even if the filesystem ACLs would allow it.
Because of these limitations it's common practice to set share permissions to full control for everyone and do the entire permission handling on the filesystem level. The simplest way of setting file ACLs is still the icacls command:
icacls C:\path\to\shared_folder /grant "DOMAIN\testuser:(CI)(OI)RX"
icacls C:\path\to\shared_folder\subfolder /grant "DOMAIN\testuser:(CI)(OI)M"
You could also use Set-Acl to the same end, but it'd require more code:
function New-Ace($user, $permission) {
New-Object Security.AccessControl.FileSystemAccessRule $user, $permission, 'ContainerInherit, ObjectInherit', 'None', 'Allow'
}
$acl = Get-Acl -LiteralPath 'C:\path\to\shared_folder'
$acl.AddAccessRule((New-Ace 'DOMAIN\testuser' 'ReadOrExecute')
Set-Acl -AclObject $acl -LiteralPath 'C:\path\to\shared_folder'
$acl = Get-Acl -LiteralPath 'C:\path\to\shared_folder\subfolder'
$acl.AddAccessRule((New-Ace 'DOMAIN\testuser' 'Modify'))
Set-Acl -AclObject $acl -LiteralPath 'C:\path\to\shared_folder\subfolder'
By enabling access-based enumeration you can make sure users will only see those folders and files they actually have access to (avoiding confusion from trying to access an object only to get an "access denied" error).

Cannot find path Powershell script on SQL Server Agent

I've been searching all the internet and stackOF to and resolve this issue.
I am trying to automate a db restore using SQL Server Agent. The sql server agent job comprises of four steps 3 of which are tsql and one which is a powershell script.
I have created a proxy with admin credentials so that the script can be run as admin.
cd c:;
$backuppath="Microsoft.PowerShell.Core\FileSystem::\\sharedcomputer\backup";
$destpath="c:\tmp\";
get-childitem -path $backuppath | where-object { -not $_.PSIsContainer } |
sort-object -Property $_.CreationTime |
select-object -last 1 | copy-item -Destination (join-path $destpath "byte.BAK");
It copies the .bak file from the source shared folder and places it in to tmp folder on the target.
Whenever I run this through regular Powershell it works fine.
Whenever I try to run this from SQL server agent I get an error stating that it cannot find path.
I tried to even use net use to pass credentials for the shared folder. I am thinking it has to do with the fact that the folder has requirement for credentials.
I have turned of password file sharing as well on the source server but for some reason when i use windows explorer to locate the shared file it still asks for credentials initially. Once its saved and cached I can then use powershell to cd in to that folder. But none of this works when its executed from sql server agent
I was able to finally figure this out with a little help from a Windows Server guy...
Going back to answering the question. When I created a proxy agent I used the credentials that were associated with the current Domain Account i.e Domain\Administrator.
In order for the proxy to connect to the remote server it needs to have credentials on that domain.
So what I did was create another domain account on my target and source servers using the same name and password and gave it permissions to the folders I needed
That account was used in the proxy and the credential was set up as .\AccountName, so because the wildcard was in place the proxy was able to jump back and fort between the two servers and successfully transfer the files....
Hope this helps

Issue Accessing File Storage in Azure WorkerRole using Startup Script

I have an Azure Cloud Service Worker Role which needs a separate Windows Service installed to redirect application tracing to a centralized server. I've placed the installation binaries for this Windows Service in a Storage Account's file storage as shown below. I then have my startup task call a batch file, which in turn executes a power-shell script to retrieve the file and install the service
When Azure deploys a new instance of the role, the script execution fails with the following error:
Cannot find path
'\\{name}.file.core.windows.net\utilities\slab1-1.zip' because it does
not exist
However, when I run the script after connecting through RDP, all is fine. Does anybody know why this might be happening? Here is the script below...
cmdkey /add:$storageAccountName.file.core.windows.net /user:$shareUser /pass:$shareAccessKey
net use * \\$storageAccountName.file.core.windows.net\utilities
mkdir slab
copy \\$storageAccountName.file.core.windows.net\utilities\$package .\slab\$package
I always have problem here and there by using a script to access the mounted azure file drive. I believe this is more or less related to the drive is mounted only for the current user and may not always work the same when called from a script.
I ended up pulling files from azure file the hard way without network drive.
$source= $stroageAccountName
$sourceKey = $shareAccessKey
$sharename = "utilities"
$package = "slab1-1.zip"
$dest = ".\slab\" + $package
#Define Azure file share root
$ctx=New-AzureStorageContext $source $sourceKey
$share = get-AzureStorageShare $sharename -Context $ctx
Get-AzureStorageFileContent -share $share -Destination $dest -Path $package -confirm:$false
Code example here will get you a good start:
https://azure.microsoft.com/en-us/documentation/articles/storage-dotnet-how-to-use-files/
It would be harder to manage if you have more complex folder structure, but objects there are CloudFileDirectory and CloudFile, property and methods there works seamlessly for me in powershell 4.0
*Azure Powershell module is required for 'Get-AzureStorageFileContent' cmdlet

How to list folder permissions located on a different server

I'm fairly new to PowerShell and am running into a problem.
I want to do the following:
Get list of permissions/users on a single folder on a different server than where I am running my PowerShell window from.
Current command failing:
Get-acl -path "\\servername\folder"
Error Message:
Get-acl : Cannot find path '\\servername\folder' because it does not exist
Does this command only work on the local machine?
It turns out with the way permissions/authentications are setup in my environment prevented my code from working.
Here are the steps I took to verify if I could connect to the server:
Test-Path \\server\folder
This returned "False", which is why my code was breaking.
The work around I used was this:
#Step 1: remotely connect to server
Enter-PSSession -ComputerName servernamegoeshere
#Step 2: get list of permissions on folder and save to csv
get-acl E:\foldernamehere |
select -expand access |
export-csv C:\Users\usernamegoeshere\Documents\listofperms.csv |
#Step 3: close remote connection
Exit-PSSession
I still had to remote into the server and copy the csv to the location I wanted because again, any copy command to another server/share in PowerShell would not work due to permission/authentication issues.
This article explains authentication/permissions a bit better than I can:
http://blogs.technet.com/b/heyscriptingguy/archive/2012/11/14/enable-powershell-quot-second-hop-quot-functionality-with-credssp.aspx
Second way to do this with less code and not having to create a remote session thanks to user Ansgar Wiechers:
Invoke-Command -Computer server -ScriptBlock {get-acl E:\folder |
select -expand access } |
export-csv \\server\folder\accesslist.csv
With PowerShell, there are many ways to do one thing...I think this way is best/most simple! Thanks!
The command works on UNC paths as well, but UNC paths are slightly different from local paths. You need an access point to enter the file system of a remote host. For SMB/CIFS access (via UNC paths) that access point is a shared folder, so you need a path \\server\share or \\server\share\path\to\subfolder.
With an admin account you could use the administrative shares (e.g. \\server\C$\Users\Administrator), otherwise you need to create a share first.

(PowerShell) How to give a ZIP permissions to allow user to edit directly after downloading from Azure Blob

Good morning friends,
I've been writing a script in PowerShell to replace our current manual process to deploy our application to Azure Blob Storage in a ZIP folder during the Build Process in VS. I'm about done, but I've run into this issue:
When the ZIP that I upload to Azure is downloaded by anyone, the ZIP cannot be manipulated without having to extract the files first. This is something the current process is able to accomplish and I don't know how (The current process was written in C# and is done through a GUI). It needs to be editable via the ZIP because the current Updater is set to manipulate the ZIP without the extraction first.
So the initial question is: How do I set permissions on a ZIP archive that will follow it to Azure Blob Storage and then when it's downloaded on a client's machine that allow it's contents to be manipulated (The error itself at this time is that it cannot delete a file in a child folder) without extraction?
Currently, to ZIP my folder up, I use this process:
$src = "$TEMPFOL\$testBuildDrop"
$dst = "$TEMPFOL\LobbyGuard.zip"
[Reflection.Assembly]::LoadWithPartialName( "System.IO.Compression.FileSystem" )
[System.IO.Compression.ZipFile]::CreateFromDirectory($src, $dst)
and then push it to blob with:
set-azurestorageblobcontent -Container test -blob "LobbyGuard.zip" -file "$TEMPFOL\LobbyGuard.zip" -context $storageCreds -force
I've tried to set permissions on the folder prior to upload using
$getTEMPFOLACL = Get-ACL $TEMPFOL
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("Everyone", "FullControl", "Allow")
$getTEMPFOLACL.SetAccessRule($accessRule)
Which works on the current local file, but once downloaded, the permissions on the file are set as
Owner: BUILTIN\Adminstrators Access: NT AUTHORITY\SYSTEM Allow FullControl
Which is exactly the same permissions as the file that's downloaded from the current process. I'm not understanding what I'm missing here to make this work.
If necessary I can provide the DL link to our blob to show the current manual processes folder that can be manipulated IN the ZIP vs. My Scripts ZIP that cannot.
Try unblocking the file after downloading, ie
Unblock-File C:\path\yourDownloaded.zip