Changing share permissions using Powershell - windows

I'm trying to modify the share permissions of share drives on a bunch of windows servers which are running either 2008 R2 or 2012.
I worked up a script which you can find here:
Import-Module ActiveDirectory
$list = Get-ADComputer -Filter 'SamAccountName -like "*FP*"' | Select -Exp Name
foreach ($Computer in $list)
{
Grant-SmbShareAccess -Name User -CimSession Server -AccountName "username" -AccessRight Full -confirm:$false
$acl = (Get-Item \\$Computer\d$\User ).GetAccessControl('Access')
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule ("Corp\uc4serv","FullControl","ContainerInherit, ObjectInherit","None","Allow")
$acl.AddAccessRule($rule)
Set-Acl \\$Computer\d$\User $acl
Write-Host -ForegroundColor DarkGreen "Permissions granted on $Computer"
}
Write-Host -ForegroundColor DarkBlue "Command Has Completed"
But it doesn't work on 2008 servers presumably because they can't run the Get-SmbShareAccess cmdlet.
What I'm trying to do is very similar to this post here: How to set share permissions on a remote share with Powershell? but specifically on Windows servers.
I also found this code on a website (http://windowsitpro.com/powershell/managing-file-shares-windows-powershell):
$acl = Get-Acl `
\\servername\c$\Users\username\sharetest
$permission = "corp\uc4serv","FullControl","Allow"
$accessRule = New-Object `
System.Security.AccessControl.FileSystemAccessRule `
$permission
$acl.SetAccessRule($accessRule)
$acl |
Set-Acl \\servername\c$\Users\username\sharetest
But this just sets the Security on the share instead of the share permissions.
I also looked into using the Net Share command but in order to change share permissions with that, it has to delete and re-create the share drive completely.

You can use "Net Share". Use Invoke-Command to run it on each remote server.
Source - https://social.technet.microsoft.com/Forums/windowsserver/en-US/3edcabac-f1a8-4c4a-850c-8ba4697930a2/using-net-share-within-powershell
Example
Source - $server = "MYSRV" ; $user = "username" ; $SrvPath = "E:\Users\$user"
$sb = {
param($User,$SrvPath)
NET SHARE $User$=$SrvPath "/GRANT:Domain Admins,FULL" "/GRANT:$User,CHANGE" /REMARK:"Home folder for $SrvPath"
}
Invoke-Command -Computername "$Server" -ScriptBlock $sb -ArgumentList $user,$SrvPath

Related

Automate user homedirectory creation Powershell

I'm automating the process of creating LocalUsers on Windows systems. So far I used the Microsoft docs on New-LocalUser which has worked fine to create the account, this is my code so far:
function New-AdminUser {
param(
[Parameter(Position=0)]
[string] $UNameLocal,
[Parameter(Position=1)]
[string] $UDescription,
[Parameter(Position=2)]
[System.Security.SecureString] $Password
)
New-LocalUser -Name $UNameLocal -Description $UDescription -Password $Password -AccountNeverExpires -Confirm
Add-LocalGroupMember -Group "Administrators" -Member $UNameLocal
}
But this command does not actually generate the homedirectory in C:\Users\username.
I can create this by manually logging into the created user, but I want to automate this in Powershell. I couldn't find anything in the LocalAccounts module.
Is there any way to automate local account setup in Windows 10 using Powershell, without having to manually log in to a new account?
If you start a process (cmd /c) as the created user, it will create his profile. Add this to your function:
$Cred = New-Object System.Management.Automation.PSCredential ("$UNameLocal", $Password)
Start-Process "cmd.exe" -Credential $Cred -ArgumentList "/C" -LoadUserProfile
Here is the code:
param([Parameter(Mandatory=$true)][String]$samAccountName)
$fullPath = "\\srv2012r2\Users\{0}" -f $samAccountName
$driveLetter = "Z:"
$User = Get-ADUser -Identity $samAccountName
if($User -ne $Null) {
Set-ADUser $User -HomeDrive $driveLetter -HomeDirectory $fullPath -ea Stop
$homeShare = New-Item -path $fullPath -ItemType Directory -force -ea Stop
$acl = Get-Acl $homeShare
$FileSystemRights = [System.Security.AccessControl.FileSystemRights]"Modify"
$AccessControlType = [System.Security.AccessControl.AccessControlType]::Allow
$InheritanceFlags = [System.Security.AccessControl.InheritanceFlags]"ContainerInherit, ObjectInherit"
$PropagationFlags = [System.Security.AccessControl.PropagationFlags]"InheritOnly"
$AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule ($User.SID, $FileSystemRights, $InheritanceFlags, $PropagationFlags, $AccessControlType)
$acl.AddAccessRule($AccessRule)
Set-Acl -Path $homeShare -AclObject $acl -ea Stop
Write-Host ("HomeDirectory created at {0}" -f $fullPath)
}
and here is the reference:
https://activedirectoryfaq.com/2017/09/powershell-create-home-directory-grant-permissions/

delete windows.old remotely with powershell

at the moment in our company we are upgrading our windows 10 to the newest built. after the upgrade we have the windows.old folder directly under c: sometimes this folder is extremly big. how can i delete this folder remotely with powershell.
if i try to delete this folder with the explorer with \pc-name\c$ i don't have the permissions. now i want to get the acl for the folder and all subfolders with powershell but i only get the acl for the top folder. how can i get it working for the complete directory. is there any other way to delete windows.old remotly?
$computername = read-host "enter pc"
$script = {
# set ErrorAction to 'Stop' in order to catch errors
$oldErrorAction = $ErrorActionPreference
$ErrorActionPreference = 'Stop'
# you're now running this on the remote pc, so use local path
$path = Get-ChildItem -Directory -Path "C:\windows.old\" -recurse
try {
$acl = Get-Acl -path $path.FullName
$accessrule = [System.Security.AccessControl.FileSystemAccessRule]::new('username', 'FullControl', 'ContainerInherit,ObjectInherit', 'None', 'Allow')
$acl.SetAccessRule($accessRule)
$acl | Set-Acl -path $path.FullName
# output the message
"{0}`t{1} success" -f (Get-Date).ToString(), $env:COMPUTERNAME
}
catch {
"{0}`t{1} failed" -f (Get-Date).ToString(), $env:COMPUTERNAME
}
# restore previous ErrorAction
$ErrorActionPreference = $oldErrorAction
}
$result = Invoke-Command -ComputerName $computername -ScriptBlock $script
if ($result -ne $null)
{
write-host "sucess" -ForegroundColor "green"
}
else
{
write-host "no success" -ForegroundColor "red"
}

powershell start-process as admin, am i misssing something

Im trying to create a script where a domain user would be able to run IIS service on windows as a local admin using stored credentials.
$adminerpath = 'c:\programdata\adminer'
Function StoreCreds(){
$credential = Get-Credential
$credential | Export-CliXml -Path $adminerpath\data.dat
}
if (Test-Path $adminerpath){
$credential = Import-CliXml -Path $adminerpath\data.dat
Start-Process C:\windows\System32\inetsrv\InetMgr.exe -Credential ($credentials)
}
else {
New-Item -Path $adminerpath -ItemType "directory"
attrib +h c:\programdata\adminer | Out-Null
StoreCreds
}
very simple, should see if the credential is stored and then run process with -credential.
it works with anything else (like note.exe or pwoershell.exe), but when i try running this with InetMgr.exe im getting:
start-process : This command cannot be run due to the error: The requested operation requires elevation.
any help would be much appriciated

Running a powershell from rundeck(linux) display different result

I'm trying to run a powershell script from rundeck(linux), If I run the script locally[Deletes some files from multiple terminal servers](Windows server) it is working as expected however if I call it from rundeck server(winrm configured) it seems that the script cant access the remote folders I'm trying to access.
I tried running the script using the same user but still shows different result.
Script bellow:
$userAD = "someuser"
$servers = Get-Content C:\TSList.csv
$Folder = "c$\Users\$userAD\"
$TSFolderShare = "\\sharepath"
Write-Output "#####Start of script#####"
Write-output `n
Write-output "Checking if $userAD user profile exist in Terminal servers..."
sleep -seconds 1
foreach ($server in $servers) {
Test-Path "\\$server\$Folder" -PathType Any
Get-ChildItem "\\$server\$Folder"
if (Test-Path "\\$server\$Folder" -PathType Any) {
Write-output "Resetting user profile in $server.."
Get-ChildItem "\\$server\$Folder" -Recurse -Force -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
sleep -seconds 1
Write-output "Done."
if( (Get-ChildItem "\\$server\$Folder" | Measure-Object).Count -eq 0)
{
Write-output "Done."
}
}
else
{
Write-output "Resetting user profile in $server.."
sleep -seconds 1
Write-output "User profile does not exist in $server."
#Write-output "\\$server\$Folder does not exist in $server!" -ForegroundColor Red
}
}
EDIT: It seems my problem is when running my script from another script with RunAS.
Below I'm trying to access a folder from another server using ps script, but since I want to integrate this to Rundeck I need to call my ps script from my linux server using python. I did a test running the ps script directly and calling the test path script using another script with RunUs using the same user I used to run the script manually
Scenario 1
Running PS script via separate PS script with RunAS(my_account)
$username = "my_account"
$password = "my_password"
$secstr = New-Object -TypeName System.Security.SecureString
$password.ToCharArray() | ForEach-Object {$secstr.AppendChar($_)}
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $secstr
Invoke-Command -FilePath "C:\testpath.ps1" -Credential $cred -Computer localhost
(C:\testpath.ps1) Content below:
Test-Path "\\server\c$\Users\myaccount\"
result:
Access is denied
+ CategoryInfo : PermissionDenied: (\server\c$\Users\myaccount:String) [Test-Path], UnauthorizedAccessException
+ FullyQualifiedErrorId : ItemExistsUnauthorizedAccessError,Microsoft.PowerShell.Commands.TestPathCommand
+ PSComputerName : localhost
False
Scenario 2
Running C:\testpath.ps1 directly as my_account
Test-Path "\\server\c$\Users\myaccount\"
result:
True
I used session configuration in powershell to solve the issue. This way allows you to tie a credential to a PowerShell session configuration and reuse this configuration for all future connections.
https://4sysops.com/archives/solve-the-powershell-multi-hop-problem-without-using-credssp/
Thanks a lot!
You're facing a double-hop issue with Rundeck and Powershell, here the explanation. That's asked before, take a look a this, and here a good workaround. Also this to solve it.

Home folders created in powershell won't work: Access Denied

I'm having some trouble creating home folders with powershell, I create the folder
New-Item -Path "C:\Homes\" -name $username -ItemType Directory
Then I copy the ACL and disable the inheritance and add the new permissions
$Rights = [System.Security.AccessControl.FileSystemRights]"FullControl"
$Inheritance = [System.Security.AccessControl.InheritanceFlags]::"ContainerInherit", "ObjectInherit"
$Propagation = [System.Security.AccessControl.PropagationFlags]::None
$AC =[System.Security.AccessControl.AccessControlType]::Allow
$NewACL = New-Object System.Security.AccessControl.FileSystemAccessRule ($username, $Rights, $Inheritance, $Propagation, $AC)
$ACL = Get-Acl -Path "C:\Homes\$username"
$ACL.SetAccessRuleProtection($True, $False)
$ACL.SetAccessRule($NewACL)
$NewACL = New-Object System.Security.AccessControl.FileSystemAccessRule ("SYSTEM", $Rights, $Inheritance, $Propagation, $AC)
$ACL.SetAccessRule($NewACL)
$NewACL = New-Object System.Security.AccessControl.FileSystemAccessRule ("Administrators", $Rights, $Inheritance, $Propagation, $AC)
$ACL.SetAccessRule($NewACL)
Set-Acl -Path "C:\Homes\$username" -AclObject $ACL
Finally I mount the folders as H: and set it as home dir
Set-ADUser -Identity $username -Replace #{HomeDirectory=$homeDir}
Set-ADUser -Identity $username -Replace #{HomeDrive=$homeDrive}
When I login to a user and try to add a file/folder I recieve permission denied.
The Root Folder (C:\Homes) is shared and has configured permissions
#Louis J. Are you sure permissions have been set properly? I mean you should try to get ACL of the created folder using command like :
(Get-Acl H:...).Access
Then check user's rights over this directory.
By the way, do you execute your script with elevated rights?

Resources