powershell Script to save users profile when they log off their session - powershell

I am trying to create a script in PowerShell which would save the users data from this path c:\Users\[user]\Documents when the user log off.
I currently have something which could work for a single nominal user however I'd like to have something which work dynamically for every users. Here is my current script:
Copy-Item -Path C:\Users\username\Documents\ -Destination \\SRVIMP02\save\Username -force -Recurse

If you are wanting to use the current user name instead of a static name, you can leverage $env:username . This should give you the current user name.
In your case the following example should work:
Copy-Item -Path C:\users\$($env:USERNAME)\documents\ -Recurse -Destination \SRVIMP02\save\$($env:USERNAME)\ -Force

Related

How do I reference the current logged in user when a script is running?

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.

Writing a PowerShell script to copy directory and its contents to all users documents folder

First, this is my first REAL question on stack-overflow so here we go:
I am trying to use Get-ChildItem and Copy-Item to copy a directory and its contents to every user-profile that may be on a PC without knowing how many users or their usernames. However, I have run into an illegal character issue whenever I run the script or other variations of what I think are the same way to achieve the result. I think it is because of the wildcard but I do not know how I should circumvent that.
For Example:
Testing the Wildcard:
Get-ChildItem 'C:Users\*\'
I can see all the users and Power-shell Documentation from Microsoft states using the * should allow it so include all items in that folder. But whenever I extend the path to lets say:
Copy-Item 'D:\Custom Office Templates' -Recurse -Destination 'C:\Users\*\Documents\' -Force
I get an "Illegal Characters in path error."
If I replace that * with an actual username to correct the path I get what I want for a single user.
The same thing happens when trying to use.
ForEach-Object {Copy-Item -Path 'D:\Custom Office Templates' -Destination 'C:\users\*\Documents\Custom Office Templates' -Force -Recurse}
Thanks you for any assistance given :).
-Destination is read as a literal path, does not understand about wildcards. What you can do is combine what you already have with Get-ChildItem using a wildcard on -Path with a delay-bind script block on -Destination:
$source = 'D:\Custom Office Templates'
Get-ChildItem 'C:Users\*\' -Directory |
Copy-Item -LiteralPath $source -Recurse -Destination {
Join-Path $_.FullName 'Documents\Custom Office Templates'
}

PowerShell Move Files From One Server to Another

I know this has been asked a million times, but I can't seem to find anything that works for me. I don't know if there is a permissions issue or what, but I am trying to move files from one server to another using a PowerShell script in the task scheduler and it worked for about a week before it stopped working. There are no errors in the task scheduler, and I'm not well versed in PowerShell at all, I'm just trying to get something quick and simple for our CMS manager to move her files from the website to a folder on another server.
$ORG = "E:\folders\uploads\" ## enter current source folder
$DEST= "\\server-folder-structure\uploads\" ## enter your destination folder
foreach ($ORG in gci $DEST -include *.doc,*.docx,*.pdf,*.png,*.gif,*.jpg,*.jpeg,*.html,*.htm -recurse)
{
Move-Item -path $ORG -destination $DEST ## Move the files to the destination folder
}
I tried this too, in hopes it would work, but still no files are being moved.
Get-ChildItem E:\folder-structure\uploads\* -Include *.doc,*.docx,*.pdf,*.png,*.gif,*.jpg,*.jpeg,*.html,*.htm -Recurse |ForEach-Object { Move-Item $_.FullName \\server-folder-structure\uploads\ }
Am I doing something wrong? Are there permissions to folders that I need to set that I don't know about? Is PowerShell just not the best way to do this? Thanks in advance.
I believe you're making this harder than it should be (with respect to PowerShell being new to you). You don't need a loop on any of your examples if you want to pipe directly to Move-Item:
$ORG = "E:\folders\uploads\" ## enter current source folder
$DEST = "\\server-folder-structure\uploads\" ## enter your destination folder
$filterFor = "*.doc","*.docx","*.pdf","*.png","*.gif","*.jpg","*.jpeg","*.html","*.htm"
Get-ChildItem $ORG -Include $filterFor -File -Recurse |
Move-Item -Destination $DEST -WhatIf
As for what you tried, and as Mathias pointed out, you would be searching your $DEST location in which the files wouldn't exist as they would only be in $ORG; given that that's the actual source folder.
This would also overwrite you $ORG variable with the current item in your iteration in: foreach ($ORG in gci ..){ ... }.
Meaning, your Move-Item would be invalid.

PowerShell Active Directory Login Script Auto-Build

I've created an active directory account creation script using powershell 4.
My Boss has stated there's a new policy where we have to build a login script per user, is there a way to do this where it'll build the .bat file and map the drives that we specify within the script?
I know there's a way to build .txt files, but not sure about .bat.
What I need
Select Drives That The user Needs Access To
I need it to build a .bat file, mapping the drives previously specified.
Then move it to the login script folder on the DC, mapped to S
For Future reference to anybody who wants to do this.
I've managed to resolve it myself after some playing around.
$NewName = $SAMAccountName
$extension = ".bat"
$FileName = "$SAMAccountName$extension"
$ScriptDrive = "\\IPREMOVED\scripts"
Write-Output "
BAT CONTENTS" `n`n|FT -AutoSize >>LoginScript.txt
Get-ChildItem LoginScript.txt | Rename-Item -NewName $FileName
Move-Item -Path ".\$FileName" -Destination $ScriptDrive

Powershell Script to move multiple unknown files into correct locations

I am attempting to create a script for use when we perform manual data transfers at work, this can be tedious to perform when users have a ton of random data in random locations. I want to move those items from the old location on the old drive to our network location and then pull it back down. What I have below is a beta version of what I am looking to do, my issue is that I am unable to figure out why I am unable to find the current logged in user and exclude certain accounts.
$DOCDIR = [Environment]::GetFolderPath("MyDocuments")
$TARGETDIR = 'C:\TextFiles'
if(!(Test-Path -Path $TARGETDIR )){
New-Item -ItemType directory -Path $TARGETDIR
}
$Include=#("*.*")
$Path=#("C:\Users\%USERNAME%\Documents","C:\Users\%USERNAME%\Pictures")
Get-ChildItem -Path $Path -Include $Include -Recurse | Move-Item -Destination C:\TextFiles
Mind you more will be added to this but I am unsure how to get the current user and have it exclude our administrator account on the units.
Thank you for any help.
You can use the environment variable named USERDOMAIN and USERNAME to determine the currently logged on user.
if ($env:UserName -eq 'Trevor.Sullivan') {
# Do something
}
To take it one step further, you could build an array of the user accounts that you want to exclude, and then check to see if the currently logged on user account is contained in that array. Here is an example:
# Build the list of excluded users
$ExcludedUserList = #(
'User1'
, 'User2'
, 'User3'
, 'User4'
);
# Check if user is contained in exclusion list
if ('User5' -notin $ExcludedUserList) {
# Do something here
}