I am having a weird problem using Powershell and setting a HomeDirectory via the cmdlet
Set-ADUser -Identity "user" -HomeDirectory "\\fileserver\home$\user"
Even though the cmdlet is working and setting the values in the AD, the necessary folder on the fileserver "\fileserver\home$\user" will not be created.
I have also unsuccessfully tried the same with the initial creation
New-ADUser -Name "user" -HomeDirectory "\\fileserver\home$\user"
I have started the Powershell on the Exchange server as domain-admin via UAC and imported the module ActiveDirectory via
Import-Module ActiveDirectory
Instead of using the UNC-path with NetBIOS-hostnames I also tried the FQDN \fileserver.domain.local\ and also the ip adrress \ip\
If I am using the cd command to enter the UNC-path via Powershell, it does also work, I can also create directories.
cd \\fileserver\home$
mkdir test_dir
Still, the directory will not be created.
If I am using the AD GUI, and try to alter the HomeDirectory-path, the folder will be created.
Any hints?
Many thanks
PS: 2008R2 x64, Exchange 2010, 1x Exchange, 1x AD controller, 1x fileserver
It is worth mentioning the following from Hey, Scripting Guy! Blog
Remember, all we have done is edit a field in Active Directory. The
file system on the foreign server has no clue about the information
presented within Active Directory. When you edit those fields in the
GUI, the user folder and permissions are provisioned as a function of
the code within that GUI interface—they are not a function of Active
Directory.
Much like Paul suggested I think you just need to create the folder yourself. Linked in that article is information about setting permissions for the file share as well. I imagine you already have that done.
NEW-ITEM –path "\\fileserver\home$\user" -type directory -force
This is the best way to do this will be to create home folder for all users if doesn't exist. Create a schedule task with event id 4720 to do this automatically
Connect home folder path and drive letter.
Get-ADUser -filter * | % { Set-ADUser $_ -HomeDrive "H:" -HomeDirectory ('\\server\home$\' + $_.SamAccountName) }
create home folders for each users:-
ForEach( $User in (Get-ADUser -filter * | if( -not ( -HomeDrive "H:" -HomeDirectory ('\\server\home$\' + $_.SamAccountName) )
Related
So, I'm using Desktop Central to run some scripts on a bunch of machines. The script is supposed to open a zip file in the c:\users%USERNAME%\ folder, and decompress it to a folder of my choosing. The idea is to use a single script for many machines, that can leverage the c:\users\LOGGEDONUSER\downloads folder (Default TEAMS download dir). The idea is that each user will download the archive from teams, and a script will decompress and install from each users DOWNLOADS folder.
The issue is that I don't seem to know how to write a script uses a variable representing the username of the logged in user for the -path in my argument.
For instance;
Extract file
Expand-archive -path $home\Downloads\SWANDPDM_SP5.1.zip -DestinationPath C:\temp\swpdminstaller\extracted\ -Force
#Define registry values to modify to allow for no UAC
$RegistryPath = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System'
$Name = 'ConsentPromptBehaviorAdmin'
$Value = '0'
#Run reg change
New-ItemProperty -Path $RegistryPath -Name $Name -Value $Value -PropertyType DWORD -Force
#Run installer
Invoke-Item C:\temp\swpdminstaller\extracted\SOLIDWORKS_AND_PDM_2021_SP5.1\startswinstall.exe
#Define reg values to change back to default
$RegistryPath = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System'
$Name = 'ConsentPromptBehaviorAdmin'
$Value = '5'
#Run reg change
New-ItemProperty -Path $RegistryPath -Name $Name -Value $Value -PropertyType DWORD -Force
This works great if I copy the script to the machine manually, and launch the script as a user. It looks at $home and figures out the correct directory based on whomever is logged in.
However, when it runs as Desktop Central, $home doesn't mean the same location. It comes back with this;
Expand-archive : The path 'C:\Windows\system32\config\systemprofile\Downloads\SWANDPDM_SP5.1.zip' either does not
exist or is not a valid file system path.
At C:\Program Files (x86)\DesktopCentral_Agent\Computer\startup\76507\SWandPDMdecomInstall.ps1:2 char:1
+ Expand-archive -path $home\Downloads\SWANDPDM_SP5.1.zip -DestinationP ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (C:\Windows\syst...NDPDM_SP5.1.zip:String) [Expand-Archive], InvalidOpe
rationException
+ FullyQualifiedErrorId : ArchiveCmdletPathNotFound,Expand-Archive
I tried using various env variables with no luck. It seems like because it's a "Desktop central" account that's running the script remotely, I can't get it to point to the correct folder in c:\users\NAMEOFLOGGEDINUSER\
So, it thinks $home = 'C:\Windows\system32\config\systemprofile\ instead of c:\users\NAMEOFLOGGEDINUSER\
Is there a way that I can get the username of the current logged on user, assign it to a variable, and then use that variable instead of $home? Keep in mind, it needs to find the logged in user while running the script as the Desktop Central service account. I've tried running the script as various domain admins\system accounts with no luck.
I thought about doing a whoami, writing to a text file, then omitting the domain portion of the output and assigning it to a variable, but there's got to be a better way.
Any help is greatly appreciated!
EDIT: Thought I was on to something, but it didn't work. I tried;
Expand-archive -path $env:HOMEPATH\Downloads\SWANDPDM_SP5.1.zip -DestinationPath C:\temp\swpdminstaller\extracted\ -Force
I see from the comments that you found a workaround. But to answer your original question, you can't get the logged in username from the usual Powershell techniques ($env:USERNAME, whoami, etc.) when you're running the script under a different security context.
But you can check who owns the Explorer.exe process:
$User = (Get-CimInstance Win32_Process -Filter "name = 'explorer.exe'" |
Invoke-CimMethod -MethodName GetOwner).User
The "Desktop central" user will probably not have Explorer running. However, if there are multiple users logged in via RDP sessions this will return an array.
How (which command) can I use to grant permissions (full_control) to a user (service_account) on a folder using PowerShell?
Thank you!
I was trying to use icacls in my PowerShell but it's not working.
There are several ways to do this. If you don't want to install a module as James suggests above then:
# Get current access permissions from folder and store in object
$Access = Get-Acl -Path $FolderPath
# Create new object with required new permissions
$NewRule = New-Object System.Security.AccessControl.FileSystemAccessRule("MyDomain\MyUserOrGroup","FullControl","ContainerInherit,ObjectInherit","None","Allow")
# Add new rule to our copy of the current rules
$Access.AddAccessRule($NewRule)
# Apply our new rule object to destination folder
Set-Acl -Path $FolderPath -AclObject $Access -ErrorAction Stop
As James mentions though, using ACLs in Powershell without a module, whilst powerful, is also a pain. I only do it when I'm sharing scripts (so that there isn't a dependency on the module).
I would recommend using the NTFSSecurity Powershell module for setting the permissions as it's much easier to use (and understand) than acls!
To add permissions for a user is just one command.
I've shown two examples for both network paths/domain account and local folder/local user. They can be mixed in any way you can set via the GUI.
Add-NTFSAccess -Path "\\sdk\data\SHAREDIR\$NAME" -Account "Domain\K_NV_TEST_R" -AccessRights FullControl
Add-NTFSAccess -Path "C:\folder\subfolder" -Account "LocalComputerName\LocalUserName" -AccessRights FullControl
I need to create a folder called "logs" on the C: drive of all the machines in my organisation. How can i do this using PowerShell?
I have a script to create the "logs" folder however i need a way to do this on more than 100 machines in Active Directory.
Any advice?
This is the script i'm using to create the folder on my machine:
New-Item -Path c:\Logs -ItemType directory -Force
Is there a way i can apply this script to my entire organisation?
Thanks.
This is not a duplicate as i am trying to do this in a domain environment to all the machines in my organisation and not just one remote server.
Since you said it was a domain environment, you don't need to use remote execution, you can access the computer's hard disks remotely.
Get-ADComputer -Filter * | %{ $logsPath = "\\$($_.Name)\c$\Logs"; if ((Test-Path $logsPath) -eq $false) { New-Item -Path $logsPath -ItemType Directory } }
You will want to filter the output of Get-ADComputer or it will apply to every computer in your domain including the servers.
I am using powershell to extract all users from an OU who have not signed into their account in 365 number of days.
import-module activedirectory
get-aduser -SearchBase 'ou=staff,ou=brummitt,dc=DUNELAND,dc=LOCAL' -filter 'enabled -eq $true' -Properties samaccountname,lastlogondate |
Where-object {$_.lastlogondate -lt (get-date).AddDays(-365)} |
Select-Object -ExpandProperty samaccountname >>'C:\stale\brummitt.txt'
In attempt to organize the folder these are stored in I have created a folder in my servers C: drive called stale and have a folder called scripts in which the powershell scripts are stored.
When I run the script with powershell and the save extension is C:\stale\brummitt.txt it outputs all users in that OU. When the save location is C:\brummitt.txt it returns the correct users who have not signed in for over a year. Why would the results be changing based on the save location and how can this be combated?
Added:
I am running the powershell script from within the scripts folder.
Did you try using Tee-Object as a part of the pipeline?, that will give you the opotunity to check the stream to the file on console,
Admittedly, I am not a PowerShell monster, so I'm going to punt...
I am working with a client who is pulling a list of all his user shares on his CIFS server to help redirect AD HomeDirectory paths in a major file server migration. This list is being compared to the list of AD users home directories as AD currently sees them.
The problem is that some user directories use old NT Usernames (NAMEI$) and some use SAMAACCOUNTNAME$. To Additionally complicate, the share SERVER differs in AD due to an elaborate history of DNS aliases over the past 10-15 years - so even though all the users home directories currently exist on SERVERA they could be mapped to OLDSERVER3, OLDERSERVER01, or OLDESTSERVERNT4 - resulting in home directories that are all over the map.
I need to write a script that can use the SAMACCOUNTNAME from a list, then change all the server information in the home directory to \NEWSEVERNAME\CURRENTSHARE$ - hopefully using something like this:
Use UserList
From UserList, get-ADuser -Identity $_ -HomeDrive "U:" -HomeDirectory
in HomeDirectory replace \\*\ with \\NewServer\ while leaving the Share$ untouched.
Set-ADuser -Identity $_ -HomeDrive "U:" -HomeDirectory
I'm fairly certain that this can be accomplished with regular expressions, for/each loops, etc... but I can't put it together.
Thank you for your help!
I went through the same migration a short while ago. Here is what you can use to set the new server while leaving the share folder untouched.
Import-Module activedirectory
$samAccountNameList = get-content "c:\userIds.txt"
$newServer = "newFps01"
foreach ($user in $samAccountNameList) {
$adProperties = get-aduser -Identity $user -Properties homeDirectory, homeDrive
$homeDrive = $adProperties.HomeDrive
# Split original homedirectory path and grab just the share folder portion
$shareFolder = ($adProperties.homeDirectory).Split("\")[3]
$newHomeDirectory = "\\$newServer\$shareFolder"
set-aduser -Identity $user -HomeDrive $homeDrive -HomeDirectory $newHomeDirectory
}