We are currently experiencing issues with selective user accounts switching from All Computers, to The Following Computers under Logon Workstations in Active Directory.
I'd like to have a way to have a spreadsheet (CSV) that contains usernames, and then run the PowerShell script would read these values and set each user to All Computers under Logon Workstation.
Now, here is a simple script that works perfectly fine - Only thing is that you would have to enter each username manually each time you run this command:
"Set-AdUser -Identity User.Name -LogOnWorkstations $null"
Here is what I thought would work - But ends up not being the case:
$csv = Import-Csv C:\Users\administrator\Desktop\users.csv
Set-AdUser -Identity $csv -LogOnWorkstations $null
If anyone has an idea why my second script isn't working, that would be greatly appreciated!
In the seconds script shall I assume that $csv contains a list of users? If so Set-AdUser does not accept multiple -Identity's. You would need to use a loop is the simplest answer.
$csv = Import-Csv C:\Users\administrator\Desktop\users.csv
$csv | ForEach-Object{
Set-AdUser -Identity $_ -LogOnWorkstations $null
}
This is very dependent on the structure of your CSV. If it has a column for username then you would need to update the cmdlet call.
Set-AdUser -Identity $_.UserName -LogOnWorkstations $null
If the file is just a list of users then don't even bother with Import-CSV
Get-Content C:\Users\administrator\Desktop\users.csv | ForEach-Object{
Set-AdUser -Identity $_ -LogOnWorkstations $null
}
Related
Powershell beginner here working in an air-gapped, Win7 environment with Powershell 4.0 so unable to import any modules or do anything sophisticated but wondering how I can achieve generating a txt file of computers on the network that are running a specific process, say wusa.exe for Windows Updates?
I have a txt list of all the computer names already and so far have this:
$computers = gc "C:\PCList.txt"
foreach ($computer in $computers) {Get-process | out-file -Path "C:\TheseAreRunningWusa.txt"}
But obviously that displays ALL processes, any way to cut out everything aside from a specific one but also only list the ones running said process?
Thanks in advance.
The Get-Process command allows you to specify both a remote computer to run on, and what service you are looking for.
$computers = Get-Content "C:\PCList.txt"
$output = #()
foreach ($computer in $computers) {
if(Get-Process "myProcessName" -ComputerName $computer -ErrorAction SilentlyContinue) {
$output += $computer
}
}
$output | Set-Content "C:\TheseAreRunningMyProcess.txt"
Note: I used -ErrorAction SilentlyContinue as Get-Process throws an error if the process is not found.
i have written a script which acts like a gpo editor, it can get some GPO and OU and link them or unlink them depending on user's wish. now this script does work when its running on Domain Controller machine but i need it to run on a windows 10 machine workstation on the domain. so i need to do the adjusment while showing the user the GUI, all the code must invoke the commands on the dc. i dont know whats the problem but when i enter the commands manually one by one it works and when its running as a script i get errors:
for example here is a function for a link button . (i have a gui with 2 listboxes. one showing the GPO's and one showing the OU (the ou is shown as CanonicalName and not as Distinguishedname hence the $SWITCH variable to go back and forth so the user will see it in a more friendly way)
function LinkFn {
$ResultsTextBox.clear()
#This $SWITCH is used to Translate the user selection from the OU listbox from canonical back to distinguishedname
$SWITCH = Get-ADOrganizationalUnit -filter * -Property CanonicalName | Where-Object {$_.CanonicalName -eq $listBox2.SelectedItem}
ForEach ($line in $listBox1.selecteditems){
try {
Invoke-Command -ComputerName "$DCNAME" -ScriptBlock {New-GPlink -name $line -target $SWITCH -ErrorAction STOP | Out-null}
$ResultsTextBox.AppendText("`n GPO: $line HAVE BEEN LINKED Successfully.`n")
}
catch{
$ResultsTextBox.AppendText("`n$line ALREADY LINKED! TO THIS OU `n")
}}}
can someone help?
From what i see, i think there is a problem with the code line:
$SWITCH = Invoke-Command -ComputerName "$DCNAME" -ScriptBlock {Get-ADOrganizationalUnit -filter * -Property CanonicalName | Where-Object {$_.CanonicalName -eq $listBox2.SelectedItem}}
$switch is coming up empty (where it runs fine on dc), any idea why?
write your try catch block like below. You have to use $using:variable to use the variables declared outside of the scriptblock.;
try {
Invoke-Command -ComputerName "$DCNAME" -ScriptBlock {New-GPlink -name $using:line -target $using:SWITCH -ErrorAction STOP | Out-null}
$ResultsTextBox.AppendText("`n GPO: $line HAVE BEEN LINKED Successfully.`n")
}
catch{
$ResultsTextBox.AppendText("`n$line ALREADY LINKED! TO THIS OU `n")
}
Also, if the user does not have access to connect / remote to the DC, this wont work. User running the script will need admin level access to the DCs or use credentials for account that actually have access.
I am writing a script where I need to check specific applications if installed or not on a remote server. I am fairly new to PowerShell, but here is the script I have written
ForEach ($computers in $computer){
Get-WMIObject -Class win32_product -Filter {Name like "%Microsoft%"} -ComputerName $computers -ErrorAction STOP | Select-Object -Property Name,Version | export-csv "C:\progrms.csv"
}
The problem I am facing here is I can get details of only Microsoft application which are installed and if I give multiple names for filter parameter like "Microsoft", "SQL", "app1" so on. This script does not seem to work.
Please let me know what has gone wrong and what needs to be done in order to get the list of specific software's that are installed. Also, note that I will be using this script for both Windows 2008 and 2012 servers.
Remove the -Filter {Name like "%Microsoft%"} part of the script to have it return all installed software.
You probably want to be doing ForEach ($computer in $computers) rather than the other way around, assuming you're creating a $computers variable somewhere above this code with the list of computer names.
You also need to -Append to the Export-CSV command as otherwise each computers output will overwrite the output of the previous, however another issue you'll then have is knowing which software comes from which computer. You can address this by using a Calculated Property to add in the computer name to the output, as follows:
ForEach ($Computer in $Computers){
Get-WMIObject -Class win32_product -ComputerName $Computer -ErrorAction Stop |
Select-Object -Property #{N='Computer';E={$Computer}},Name,Version |
Export-Csv "C:\progrms.csv" -Append
}
Using Task Scheduler I am running a PS script to restart selected Windows Services using Restart-Service. For troubleshooting issues I'd like to write the output to a log file so we can make sure the service did restart. For the life of me I can't get the output file to write anything just creates the file in date format, but no contents.
THank you
Edit:
OG Script
Restart-Service Printer Spooler -Force | Out-File c:\scripts\test3.txt
If I add -PassThru I get an output but the output is pretty bare bones. Would like to log steps of the Service Controller.
Restart-Service Printer Spooler -Force -PassThru | Out-File c:\scripts\test3.txt
$logFile = "C:\Windows\Temp\out.txt"
$serviceName = "serviceName"
Restart-Service $serviceName -Verbose *> $logFile
The -Verbose switch gives you detailed start/stop attempt information
*> Redirects all command output to the log file.
Provided the service you're restarting talks to the eventlogs, I'd grab the data from there and log it. Or leave it in there and grab it as needed. If you want to output it, this is one approach:
$date = (get-date).AddMinutes(-5)
$serviceData = Get-Service wersvc
restart-service $serviceData
$eventData = Get-Winevent -FilterHashtable #{ LogName = 'System'; StartTime = $date; ID = 7036} | ? {$_.message -match $serviceData.DisplayName}
$eventData | Out-File C:\logs\filename.txt
I have a Windows XP system and the user accounts are configured to have their passwords expire in 45 days option set. I am trying to figure out, either manually or via the use of a batch file, what the password expiry date is based on the current user logged in. I know that there are VBScript files that can accomplish this, but these pc's are configured to not execute VBScript files, therefore I need to either look this up manually or batch files.
Thanks!
If this is just on one computer, one user, and ran locally...
net user username | findstr "expires"
Multiple machines ran remotely for one user account... put all computer names or IP's in a text file (i.e. systems.txt)
psexec #systems.txt net user username | findstr "expires"
psexec is free from sysinternals
If you want to know the expiration date on all local users on multiple network computers you can use powershell and psexec (remote machines do not require powershell), like so...
$systems = get-content .\systems.txt;
foreach ($sys in $systems) {
foreach ($token in (Get-WmiObject Win32_UserAccount -ComputerName $sys -Filter "Domain='$sys'" | Select-Object -Property Name |ft -AutoSize -HideTableHeaders >> "$sys.txt")) { echo $token };
(cat "$sys.txt") -replace ' {2,}','' | ? {$_ -ne ''} | sc "$sys.txt"
foreach ($strUser in (get-content "$sys.txt")) {psexec \\$sys net user $strUser >> "$sys-accounts.txt"
}
}
you may need to tweak the script a little... hope this helps.