Deleting all locally stored user profiles on log off - powershell

I want to delete all locally stored user profiles on logoff using a Powershell script. I've the following script:
Set-ExecutionPolicyRemoteSigned[gc]::collect()
cmd /c start reg unload "HKCU"Remove-PSDrive HKCU import-module C:\Windows\System32\WindowsPowerShell\v1.0\Modules\ManageUserProfiles\ManageUserProfiles.PSM1
get-userprofile |where{ $_.SID -ne ("S-1-5-21-3071724114-2656578308-4228372245-500")} | remove-userprofile
I'm a complete newbie to powershell. So could someone tell me whether this script meets my needs and how does it run? And could you also explain what $_.SID -ne ("S-1-5-21-3071724114-2656578308-4228372245-500") means too. Thanks in advance.

I am not familiar with the module that you are running, and it looks like that should be 6 lines not 3 (insert break before [gc], before Remove-PSDrive, and before Import-Module).
Next, add a space between Set-ExecutionPolicy and RemoteSigned.
Now, the script appears to collect user profiles, pipes them through a Where statement that excludes the Administrator account from the list of profiles, and then removes all remaining profiles. Let's step through it...
Set-ExecutionPolicy RemoteSigned
This sets your execution policy. I'm going to assume this is to avoid issues with an unsigned module that you load in a couple steps.
[gc]::collect()
This forces the garbage collection to clean up memory and remove unused resources. This line can probably be skipped.
cmd /c start reg unload "HKCU"
This uses the reg.exe command line application to unload the HKEY_CURRENT_USER hive from within the current registry set. This would need to be done before deleting a profile since you can't delete files that are in use.
Remove-PSDrive HKCU
This does pretty much the same thing, but for PowerShell's registry provider. I'm guessing this is so that you don't get errors, or so that it doesn't try to reload the HKCU hive.
C:\Windows\System32\WindowsPowerShell\v1.0\Modules\ManageUserProfiles\ManageUserProfiles.PSM1
This loads the 'Manage User Profiles' module. I am not familiar with the module, but you would need to make sure that you have that module installed on the computer that this is running on, so if you are running this on all of your computers you need to install that module on all of your computers.
get-userprofile |where{ $_.SID -ne ("S-1-5-21-3071724114-2656578308-4228372245-500")} | remove-userprofile
This is a command from the module you just loaded. It will, I assume, get user profiles as some sort of custom object, and then it pipes to a Where statement that excludes the Administrator account by stating that it only allows profile objects that do not (-ne is the 'not equal' operator) have a SID property equal to "S-1-5-21-3071724114-2656578308-4228372245-500". So all user profiles except the admin account's profile are then piped to the Remove-UserProfile command, which we can probably assume deletes each profile that is piped to it.
Hopefully that explains what your script is doing.

Related

How to run powershell script on computer start-up

I am trying to run a PowerShell script Daily.ps1 on start-up, however, due to administrator settings (I cannot run as admin, that is not an option), I cannot run it through the Task Scheduler. For example, this is the contents of Daily.ps1:
if (1 -eq 1) {
"Hello there!"
}
So I tried to have a batch script Daily.cmd run on start up (through the start-up folder), which runs, but I cannot get it run the Daily.ps1, and I get a message saying running scripts is disabled. (Both files are in the same directory)
powershell C:\Users\Simon\Desktop\Daily.ps1
File C:\Users\Simon\Desktop\Daily.ps1 cannot be loaded because running scripts is disabled on this system
I then tried using this line of code from a trick I learned to bypass running scripts directly:
powershell cat Daily.ps1 | powershell invoke-expression
This works but only for one liners. So I added the -raw flag for
cat, which works when in powershell, but not in CMD. For some reason, Daily.ps1's text is still stored as an array of strings. (apologies for formatting)
cmdlet Invoke-Expression at command pipeline position 1
Supply values for the following parameters:
Command: if (1 -eq 1) {
invoke-expression : At line:1 char:14
if (1 -eq 1) {
Missing closing '}' in statement block or type definition.
At line:1 char:1
invoke-expression ~~~~~~~~~~~~~~~~~
So I tried to add this to Daily.cmd:
powershell
cat -raw Daily.ps1 | powershell-invoke-expression
However, the rest of the script doesn't get executed at all once I enter PowerShell.
I don't know to get Daily.ps1 to run through a batch command. Is there a way I missed, or is one of the ways I tried faulty (without admin rights)?
Edit: To clarify, ExecutionPolicy is set to Restricted, and that cannot be changed. Additionally, I can run PowerShell scripts fine through right clicking the file and running with PS.
Create a scheduled task to run at computer startup. Put powershell.exe in the field "program/script" and -File "C:\path\to\your.ps1" in the field "arguments" (you may want to avoid placing the script in a user profile). Set the task to run whether the user is logged on or not.
I found an answer!
After trying many different methods, I came across this line of code that allows you to run PS scripts if ExecutionProperty is set to restricted:
start powershell "cat -raw C:\Users\Simon\Desktop\Daily.ps1 | invoke-expression"
This runs powershell and uses the trick of piping the results of cat -raw [file.ps1] to invoke-expression. This is useful workaround if ExecutionProperty is set to restricted.
Then you can save this line to a .cmd or .bat file and use either Task Scheduler (more customizability) or put it in the startup folder.
P.S. for everyone who kept saying change the ExecutionProperty to something other than restricted. I clearly stated multiple times that I cannot do that(not admin), nor will the Sys Admin do that, nor will it ever happen(must stay restricted) :)

There is an inconsistency concerning the location of powershell's profile on my windows 7 machine

I created a profile.ps1 in the same directory that contains the powershell executable, which on my machine is C:\Windows\System32\WindowsPowerShell\v1.0
The profile file is definitely executed when I run powershell.exe
However when I enter $profile at the powershell prompt, the following non-existent filename is returned
C:\Users\richard\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.psi
Does anyone know how this inconsistency may have happened and what steps should I take to resolve it?
$Profile is a string, but it has 4 note properties with possible locations to put profile scripts. Each is selected depending on which user and which host is being executed.
To see all 4, use something like this
$profile| select-object *Host* | format-list
The list you get will show profile script locations that would be run for you and this host.

Group Policy Issue

I'm hoping you can help. For a bit of background one of our Domain Controllers is Server 2008 R2 and the other is 2012 R2, the 2012 R2 contains the more recent ADMX files. The primary DC is the 2008 version and we plan on upgrading this soon.
I have a Default Domain Policy that contains a basic logon script (.bat) that maps drives and adds documents to users desktops. This policy is Enforced and Link Enabled and pushes to all OU's.
I have an additional Policy setup within an OU that is linked to our domain, this includes a Powershell script that runs at logon. This was created on the secondary DC (2012) as it uses the "Start Screen Layout" feature within Start Menu and Taskbar - the primary DC (2008) doesn't have this features available.
For some reason the Default Domain Policy isn't running, the second policy however is successfully running. Is there any reason this might be happening? I've had a mess with the enforcement options for the second policy but I can't fathom out why it's not running both.
It's definately something to do with the Powershell commands I have running in the second policy, if I remove these the default policy login scripts run fine.
Some More Info
To explain, there's 3 scripts in total (all of which sit in the Policy location within sysvol). The first ps1 file copies a shortcut for devices and printers from a network location that all users have access to and pastes it into %appdata% for all users. Part of this script uses the startlayout.xml to reference this location which then add the shortcut to the users start menu.
Copy-Item -Path "\\Server\Share\*.lnk" -Destination "$env:APPDATA\Microsoft\Windows\Start Menu\Programs"
The next command removes a load of the bloatware that Win 10 installs to a users profile, I won't post all of the apps in the script but a few so you get the gist:
$AppList = #(
"*Microsoft.3dbuilder*"
"*AdobeSystemsIncorporated.AdobePhotoshopExpress*"
"*Microsoft.WindowsAlarms*"
"*Microsoft.Asphalt8Airborne*"
)
foreach ($App in $AppList) {
Get-AppxPackage -Name $App | Remove-AppxPackage -ErrorAction SilentlyContinue
}
The script that is added as the actual logon script references the location the two scripts above sit in and run them:
Get-ChildItem \\domain\SysVol\domain\Policies\'{Policy Number}'\User\Scripts\Logon | ForEach-Object {
& $_.FullName
}
Hope this helps, whether or not there's isn't an exit command maybe I'm not sure as I'm not too savy with Powershell scripting.
Further Update
Hi All, another update. I've made all my drive mappings and document copies through Group Policy now which eliminates the first policy therefore there is only one logon script that should run now which is to remove the Bloatware. I've decided to try and call it from a .bat file using the following command:
PowerShell.exe -NoProfile -ExecutionPolicy Bypass -Command "& {Start-Process PowerShell -ArgumentList '-NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -File "\\domainm\SysVol\domain\Policies\{Policy Number}\User\Scripts\Logon\BloatwareRemoval.ps1"'-Wait}"
Again this will only run after a user logs on for the second time. Is there something glaringly obvious I'm missing here?Thanks in advance.
Thanks in advance.

Running a cmd in powershell referencing a UNC path

I’m in the process of creating a powershell script to check OU users against users already configured for file share archiving but I’ve hit a stumbling block. I can query AD to get a list of users per OU and their home directories, dumping all of the details out to text files for logs and basing subsequent queries on. Once I have these details I try to run a dos command, (Enterprise Vault) Archivepoints.exe passing variables to it. The command would usually be :
Archivepoints.exe find \\fopserver045v\ouone_users$
When I try to run the following code I get an error.
$app="D:\Enterprise Vault\ArchivePoints.exe"
$EVArg = "find"
$VolLine = "\\fopserver045v\ouone_users_r$"
Invoke-Item "$app $EVArg $VolLine"
Invoke-Item : Cannot find path 'D:\Enterprise Vault\ArchivePoints.exe find \fopserver045v\ouone_users_r$' because it does not exist.
At first I thought it was missing the first backslash of the UNC path that was causing the issue but I'm no longer sure.
The script and command run on the EV server and the UNC bath doesn't actually go to the server, it's only a reference path within EV so it's not a credentials issue.
I need to be able to log the output to file too if possible.
What should the code look like and should I be using invoke-command or Invoke-Expression instead ?
Thanks
Don't use Invoke-Item. External commands should be run using the call operator (&). You can use splatting for the argument list.
$app="D:\Enterprise Vault\ArchivePoints.exe"
$arguments = "find", "\\fopserver045v\ouone_users_r$"
& $app #arguments

Using $env:username in a logon script is not working

I have this setup with a GPO to run as a logon script, obviously to map a drive for clients.
net use H: \\server1\share\$env:username
Dead simple. If I put in a specific username in place of the variable then it works. Also, if I run this script directly on a client machine it works.
Do you get an error? Does it helps if you wrap the path in double quotes?
"\\server1\share\$env:username"
That should work with or without the quotation marks. Are the clients all Windows 7? I believe that Powershell logon/startup scripts don't work on earlier versions, even if you have Powershell installed, because it's an add-on rather than a native shell. If you're using downlevel clients, you can invoke the powershell script from a cmd batch file. But if you're going to do that, might as well skip Powershell and just run net use H:\\server1\share\%username% from your batch file.
Run this in a .bat file as a login script (use a FQDN for the server name):
net use H: \\server.example.com\share\%USERNAME%
If that not works, your GPO is just not yet applied. You can force that by running on the machine gpupdate /force.
For testing make sure that the GPO is applied to the right OU to the group "Authenticated Users" (computers are in the group too). And if that is not working, you can also "Enforce" the GPO. Don't forget to do a gpupdate /force after any change to the GPO or it settings.
You can also try a .js logon script like:
var WSH = new ActiveXObject("WScript.Shell");
// Map share
WSH.Run("net use H: \\\\server.example.com\\share");