How to set share permissions on a remote share with Powershell? - powershell

I need to set the share permissions of a remote share from a Powershell 4 script. I've looked at this page, specifically the command Grant-SmbShareAccess but that cmdlet sets permissions on local shares, I would love to have seen a -ComputerName parameter but, alas, there isn't one.
I want to do something like: Grant-SmbShareAccess -ComputerName MYREMOTESERVER -Name <share_name> -AccountName <domain_account> -AccessRight Full
Any ideas on how to do this? My remote server could be a Windows Server or a NetApp vFiler.
EDIT
I tried Matt's suggestion of Invoke-Command in the comments against a NetApp vFiler and got this error:
Connecting to remote server MYREMOTESERVER failed with the following error message : The client cannot connect to the destination specified in the request. Verify that the service on the destination is running and is accepting requests. Consult the logs and documentation for the WS-Management service running on the destination, most commonly IIS or WinRM. If the destination is the WinRM service, run the following command on the destination to analyze and configure the WinRM service: "winrm quickconfig".
Changing the security of the share in Windows Explorer works fine.

Grant-SmbShareAccess is a CDXML command, which means that it uses CIM. As you've already noticed, it should only work on a Windows system running at least PSv3 (in this case the WMI class used only exists on Windows 8 and Server 2012 or higher).
There may be other ways to do this against a non-Windows server, but I would try the PowerShell Access Control Module:
$SharePath = "\\ServerName\ShareName"
$Principal = <account name here>
# Add permission to $Principal (-Force will suppress the prompt)
Get-SecurityDescriptor -Path $SharePath -ObjectType LMShare |
Add-AccessControlEntry -Principal $Principal -LogicalShareRights FullControl -Apply #-Force
# Verify:
Get-SecurityDescriptor -Path $SharePath -ObjectType LMShare |
Get-AccessControlEntry
I honestly don't know if this will work since I've only tested it against Windows servers and I don't deal with share permissions very often. Try it out, and if it works, I'll take this part out of the answer.

For Windows Server SMB shares, use the -CimSession parameter.
For non-Windows SMB shares, I would not expect the Windows SMB administration cmdlets to work with them.

The Netapp Powershell toolkit will help with this. Once installed you can import the module into your script, and manage your shares. Here is a rough example that connects to a filer, prompts for a sharename, then configures that share with some default permissions:
# Import the Netapp Powershell Module
import-module dataontap
# Connect to the filer
connect-nacontroller *filername*
# Get the sharename
$sharename = Read-Host -Prompt 'Enter the share you want to configure'
# Configure the CIFS Permissions
Set-NaCifsShareAcl $sharename "Authenticated users" -AccessRights "Change"
Set-NaCifsShareAcl $sharename filername\administrators -AccessRights "Full Control"
Set-NaCifsShareAcl $sharename domain\somegroup -AccessRights "Full Control"
Remove-NaCifsShareAcl $sharename everyone

Related

Can't enter remote powershell 7.1 session

Been able to do it against Microsoft.PowerShell (5.1), but today I hit a known issue on 5.1 with remote Copy-Item so I installed PowerShell 7 on the remote server (checking "Enable Remoting" in the installer) and am trying to get it working.
$securePassword = ConvertTo-SecureString -AsPlainText -Force -String $Password
$credential = New-Object -TypeName system.management.automation.pscredential -ArgumentList $Username, $securePassword
$session = New-PSSession $targetMachineHostName -Credential $credential -ConfigurationName "Microsoft.PowerShell"
Enter-PSSession $session
Above works. But if I change ConfigurationName to "PowerShell.7.1.0" I get:
[myserver.com.au] Connecting to remote server myserver.com.au failed with
| the following error message : <f:WSManFault
| xmlns:f="http://schemas.microsoft.com/wbem/wsman/1/wsmanfault" Code="2689860592"
| Machine="myserver.com.au"><f:Message><f:ProviderFault provider="PowerShell.7.1.0"
| path="C:\Windows\system32\PowerShell\7.1.0\pwrshplugin.dll"></f:ProviderFault></f:Message></f:WSManFault> For more information, see the about_Remote_Troubleshooting Help topic.
On the remote server I've run enable ps remoting in a 7.1 powershell so if I run Get-PSSessionConfiguration it returns a bunch of configurations, including the following:
Name : PowerShell.7.1.0
PSVersion : 7.1
StartupScript :
RunAsUser :
Permission : NT AUTHORITY\INTERACTIVE AccessAllowed, BUILTIN\Administrators AccessAllowed, BUILTIN\Remote
Management Users AccessAllowed
The dll the error refers to exists on the machine.
The user credentials I'm using are for a Local User on the remote machine that isn't an Administrator, but belongs to the Remote Management Users group.
Also worth noting from the remote machine itself (as a different Adminstrator local account, I can start a session to localhost).
After making the user an Administrator I was able to connect, but I'd gone to great lengths earlier to make non-Adminstrator possible on 5.1.
Out of interest, I tried giving the user Full Control to C:\Windows\system32\PowerShell\7.1.0 and then I could connect...
Still would love to know what's going on though and whether I'm doing the right thing or minimum permissions required.
It seems like the minimum security permissions to the folder are:
Read & Execute
List folder contents
Read
Write
Write is bizarre, but without it I get that error. I've assigned those permissions to the "Remote Management Users" group.
Docs here touch a little bit on v5.1 vs v7, and then link to here mentioning an install script so maybe something has fallen through the cracks.
I was getting the same error. I installed PowerShell 7 from Microsoft Store and then ran Enable-PSRemoting. I got this error so I uninstalled it and reinstalled it from WinGet which uses the MSI. That didn't work either. I tried running Enable-PSRemoting again, but nothing changed.
I ran Install-PowerShellRemoting.ps1 and it gave me two errors about things already existing and did not fix the problem. However, I was able to resolve the problem by doing the following:
Delete the PowerShell 7 plugins: Remove-Item 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WSMAN\Plugin\PowerShell.7','HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WSMAN\Plugin\PowerShell.7.1.1'.
Run Install-PowerShellRemoting.ps1 again.
I'm not sure what the difference was, but deleting and allowing the script to generate it again fixed it for me.

Connecting Exchange Online Fails when passing proxy and running in System PowerShell - TokenProvider Returns Object Reference Error

I was connecting Exchange Online using a PowerShell window that is opened with system access. I used PSExec on an elevated Command Prompt to open the System access PowerShell. Below is the command.
PSExec -i -s PowerShell
On the PowerShell, I imported the latest Exchange Online Management PowerShell module version 2.0.3. I use the app-based authentication described here: https://learn.microsoft.com/en-us/powershell/exchange/app-only-auth-powershell-v2?view=exchange-ps#setup-app-only-authentication.
There is one more website that shows how to connect with app-based authentication: https://o365reports.com/2020/07/04/modern-auth-and-unattended-scripts-in-exchange-online-powershell-v2.
Below are the commands used to connect to Exchange Online.
Import-Module .\ExchangeOnlineManagement
$sessopt = New-PSSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck -ProxyAccessType IEConfig
$certkey = ConvertTo-SecureString "<EnterCertificateKeyHere>" -AsPlainText -Force
Connect-ExchangeOnline -CertificateFilePath "pfx Certificate Path" -AppId <EnterAppIdHere> -Organization "domain.onmicrosoft.com" -CertificatePassword $certkey -PSSessionOption $sessopt -verbose
When running the above, it returns Object Reference error. I got excited and went on to find what the error is by decompiling the DLL files and found that inside the 'ExoPowershellGalleryModule.dll -> NewExoPSSession.cs' of the Exchange module, the 'GetAccessToken' function which is called around line:308 causes this error. Any idea what makes the Object reference not set to an instance of an object. System.Management.Automation.RemoteException: Object reference not set to an instance of an object. error. Was the proxy not taken from IE?
I've set the proxy settings in IE using the below Powershell command-lets in system PowerShell.
Set-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings' -name ProxyServer -Value "ProxyServerAddress"
Set-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings' -name ProxyEnable -Value 1
Any help to resolve this is appreciated.
If your using
PSExec -i -s PowerShell
Then the proxy information your entering for the user will have no effect because the local system account will have its own profile information. Also if the proxy needs authentication you also won't be presenting any Network credentials.
If you really want to run under the system account you could try using netsh to configure the proxy https://learn.microsoft.com/en-us/windows/security/threat-protection/microsoft-defender-atp/configure-proxy-internet but if you proxy need authentication this won't work.

Change BIOS password through powershell

I want to build a script to change and/or set up BIOS password to HP workstations.
Script i run as follows:
C:\> $computers=Get-Content -Path c:\computers.txt
C:\> foreach ($computer in $computers) {
$passChange=Get-WmiObject -computername $computer -Namespace root/hp/instrumentedBIOS -Class HP_BIOSSettingInterface
$passChange.SetBIOSSetting('Setup Password','<utf-16/>MYNEWPASSWORD','<utf-16/>')
}
Now, the following happen:
If my BIOS has no password, the script works just fine!
If my BIOS has password already, script has Return: 6. I suppose there is
a different option for changing the BIOS password?If yes, any help
is appreciated!
If i run the script for my computer, it works.
If i run the script for another computer i get the following error:
The RPC server is unavailable. (Exception from HRESULT: 0x800706BA).
Is there a way to enable an option to enable the RPC for this feature and then disable it again?
Thank you in advance
According to HP's documentation HP Client Management Interface the WMI interface supports remote interfacing.
You need to ensure all remote computers you're attempting to connect to have the HP custom WMI Namespace.
You also need to ensure the account you're running under has administrative permissions on all of the remote computers.
You may also need to explicitly set the impersonation to 3 which is impersonate.
For more information: Connecting to WMI Remotely with PowerShell
Also ensure the firewall on the remote computers is either off or has exclusions for WMI

How to disable windows firewall for all networked machines using the command line in Windows Server 2016?

I am currently building a Hyper-V lab consisting of a DC and multiple networked VMs, using Windows Server 2016. I'd like to completely disable the windows firewall for all existing and newly created VMs.
The best way that I've found to do this so far is via Group Policy for the Domain Profile. Then set Windows Firewall: Protect all network connections to disabled. What I would like to do is to have a way of scripting this out (using Powershell if possible).
I've found that by performing the above steps in the GUI, it creates a few entries in the registry:
HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile
HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Policies\Microsoft\WindowsFirewall\DomainProfile
In each of those entries, there is a property called EnableFirewall which is set to 0. So I tried creating all of this using Powershell like this:
New-Item -path "HKLM:\SOFTWARE\Policies\Microsoft" -name WindowsFirewall
New-Item -path "HKLM:\SOFTWARE\Policies\Microsoft\WindowsFirewall" -name DomainProfile
New-ItemProperty -path "HKLM:\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile" -name EnableFirewall -value 0 -PropertyType DWord -Force
Unfortunately it doesn't seem to be working, so there must be something else that I'm missing.
Does anybody know how to completely disable the windows firewall for all networked machines using the command line in Windows Server 2016?
Setting up the Windows-Firewall for your domain-computers through computer-startup-script is not a great solution in my opinion.
You should definetly use Group Policy for this task.
GP does exactly what I want, I would just like a way of modifying GP using Powershell. I'm building a lab from scratch, and I'm looking to script as much of it as possible rather than using the gui.
I am not completely sure, what you are trying to achive.
You have created a lab now and I think you are trying to script a complete automatic built-up for future use. Is this correct?
If yes, then my solution is maybe what you are looking for:
Create a new GPO in your lab named "Firewall-Settings" for example.
Make all of your needed FireWall-Settings to the new GPO.
In Group Policy Editor open the main-node named „Group Policy Objects“. (important) Find the newly created GPO, right-click it and select "Backup":
Save the GPO-backup to a folder. (folder must exist)
The GPO is beeing saved and named like on the screenshot below (GUID):
That's it for the preparation. Now you maybe want to script the creation of the GPO with Powershell for future use and import the backup to obtain it's settings in a new environment:
New-GPO -Name "FireWall-Settings" | New-GPLink -Target "DC=mydomain,DC=local" # distinguishedName of Target-OU
Import-GPO -Path $PathtoGPOBackup -TargetName "FireWall-Settings" -BackupGpoName "FireWall-Settings"
The Script creates a GPO in the new environment with the name "FireWall-Settings" and links it to the target-OU.
After that you import the settings of the backup-GPO. All the domain-members in scope of the GPO will get the Windows-Firewall configured automatically.
Now the process is documented and fully automatic, if this is, what you are looking for.
Kind regards
open cmd prompt with elevated mode and run this:
netsh -r ComputerName -u Username -p Password -c advfirewall set allprofiles state off
If you want to do it for all the machines. Get all the ad computers using get-adcomputer. Run a foreach loop and put the variable istead of computername.
If you have the domain admin creds, then you are good to go with this.
Hope it helps.
Depending on the profile you want to disable, specify profiles (public, domain, private) using the -Name parameter. To disable all profiles for a networked machine, where $computerName array is the hostname of your DC, PC etc:
$computerName = 'DC1, PC1, MS1'
Invoke-Command -Computername $computerName -ScriptBlock {
Set-NetFirewallProfile -Name Domain, Public, Private -Enabled False
}

PowerShell 2.0: Accessing Windows Shares during a Remote Session

I am having trouble accessing a shared network location while within a PowerShell remote session.
From the PowerShell prompt, I enter a new session:
Enter-PSSession server1
The session is properly created and entered. I then attempt to list the contents of the share:
dir \\server2\share1
The response is this error:
Get-ChildItem : Cannot find path '\\server2\share1' because it does not exist.
However, if I remote desktop into server1, bring up PowerShell, and execute the very same dir command, the contents are correctly listed.
I've tried various things using credentials, but that doesn't seem to fix it. I've also confirmed via the "whoami" command that I have the same identity in both examples.
What would cause this?
If you can't use credential delegation as mentioned above, you can mount (or just authenticate as below) the remote share in the remote session using explicit credentials, e.g.
[server1] ps> net use \\server2\share * /user:username
(prompts for password)
[server1] ps> dir \\server2\share
(listing)
This problem has nothing to do with powershell per-se; you are trying to replay your local credentials in a remote session to a third location and falling foul of the NTLM "double hop" limitation.
Read the section "Credential Delegation"
Here - Credit to Keith Hill
and perform the steps if you have not already done so.
Another option is kerberos resource delegation
eg:
$server_name = "my-server" $servers = #(get-adcomputer -identity $server_name)
$target = "target-server" $tgt_srv = get-adcomputer -identity $target
Set-ADComputer -Identity $to_delegate -PrincipalsAllowedToDelegateToAccount $servers