I have a task set up via GPO that is running a PowerShell script. I have found out that Get-ADUser can only be used if the module is available on the machine you are running the script on. Is there another way of seeing if a user is in a specific group when running on several client machines that I do not want to install anything extra on? This was easy with VBScript, but I'm not sure how else to do it with PowerShell. Here is the one line that is not working on machines without AD:
If ((Get-ADUser $User -Properties memberof).memberof -like "CN=GROUP*")
With VBScript, the following works on all machines:
If IsMember("GROUP") Then
First you need to get the DistinguishedName(See Function Above) of the user, and your DomainController name, then you can use [ADSI] type without the active directory module, like this:
DC = Name of your DomainController //DC/$UserDN
Function Get-DN ($SAMName)
{
$root = [ADSI]''
$searcher = new-object System.DirectoryServices.DirectorySearcher($root)
$searcher.filter = "(&(objectClass=user)(sAMAccountName= $SAMName))"
$user = $searcher.findall()
if ($user.count -gt 1)
{
$count = 0
foreach($i in $user)
{
write-host $count ": " $i.path
$count = $count + 1
}
$selection = Read-Host "Please select item: "
Return $user[$selection].path
}
else
{
return $user[0].path
}
}
$GroupName = "MyGroup"
$UserDN = Get-DN $env:USERNAME
$user = [adsi]$UserDN
if ($User.memberOf -match $GroupName)
{
"The User is Member of $GroupName"
}
else
{
"The User is not Member of $GroupName"
}
Related
I have a script that uses an input file with users SamAccountName. It goes thought the script and updates the users profile to check mark the
"Deny this user permissions to log on to Remote Desktop Session Host Server".
Once the value is set I also want to read it to make sure it got changed properly.
For most users it works but for some it will say it changed but it actually is not.
$ADUsers = Get-Content "C:\PSTOOLS\Passwordneverexpire\disable-enbale deny logon.txt"
ForEach ($User in $ADUsers) {
$UserDN = (Get-ADUser -identity $User).distinguishedName
if ($UserDN) {
$Command = [ADSI] "LDAP://$UserDN"
$Command.psbase.invokeSet("AllowLogon",0) # it will NOT allow remote logon
$Command.setinfo()
Write-Host $User + "Allow logon " + $Command.psbase.InvokeGet("AllowLogon") -as [Boolean]
}
else {
Write-Host "$UserDN Does Not Exist"
}
}
AllowLogon has 3 state possible :
Enabled = $true
Disabled = $False
Never Defined = ERROR on read !
you can use this code
$AdsiItem = [adsi]"LDAP://$($item.DistinguishedName)"
try {
$AllowLogon = $AdsiItem.InvokeGet("AllowLogon")
} catch {
# unreadable, because it is never defined
$AllowLogon = $Null
}
if($AllowLogon -eq $true) {
'TSE authorized!'
} elseif ($null -eq $AllowLogon ) {
'TSE not forbidden!'
} else {
'Forbidden!'
}
My script used in each pc in our network to rename pc but i want to check domain is the new name is already exist
Any help please
$Searcher = New-Object -TypeName System.DirectoryServices.DirectorySearcher
$searcher = [adsisearcher]"(&(objectCategory=computer)(objectClass=computer)(name=$global:NewComputerName))"
$searcher.PropertiesToLoad.AddRange(('name'))
$searchResult = $searcher.FindAll()
if($searchResult.count -eq 1)
{
$Result = $true
}
else
{
$Result = $False
}
So then i use this to check if the result is true or false
elseif ($Result -match 'true')
{
$msgBoxInput7 = [System.Windows.Forms.MessageBox]::Show('computer is exist', 'OK')
switch ($msgBoxInput7) {
'OK' {
$groupbox1.ResumeLayout()
$form1.ResumeLayout()
$form1.add_FormClosed($Form_Cleanup_FormClosed)
}
}
}
Please help me this code doesn’t work
Try to use Get-ADComputer (as Theo said in the comment):
if(get-adcomputer -filter "Name -eq 'nameToFind'"){
"Exists"
}else{
"Not exists"
}
If you will receive error like:
The term 'Get-ADComputer' is not recognized as the name of a cmdlet, function etc..
You need to import the module before this command using Import-Module ActiveDirectory
You may even receive another issue:
Get-ADComputer : Unable to find a default server with Active Directory Web Services running
If so, please add parameter -Server with AD server name, example:
if(get-adcomputer -Server "DC" -filter "Name -eq 'nameToFind'"){
"Exists"
}else{
"Not exists"
}
I'm looking at creating a local administrator on a handful of machines (>30). I don't really want to use GPO if I can get away with it. LAPS is a little overkill for what I need.
I found a nice script online but it only creates the user and doesn't add them to the administrators group. Can anyone see the error?
#Define variables
$computers = Get-Content C:\Computers.txt
#$computers = Import-CSV C:\Computers.txt | select Computer
$username = "Admin"
$password = "Password99"
$fullname = "Admin"
$local_security_group = "Administrators"
$description = "Description"
Foreach ($computer in $computers) {
$users = $null
$comp = [ADSI]"WinNT://$computer"
#Check if username exists
Try {
$users = $comp.psbase.children | select -expand name
if ($users -like $username) {
Write-Host "$username already exists on $computer"
} else {
#Create the account
$user = $comp.Create("User", "$username")
$user.SetPassword("$password")
$user.Put("Description", "$description")
$user.Put("Fullname", "$fullname")
$user.SetInfo()
#Set password to never expire
#And set user cannot change password
$ADS_UF_DONT_EXPIRE_PASSWD = 0x10000
$ADS_UF_PASSWD_CANT_CHANGE = 0x40
$user.userflags = $ADS_UF_DONT_EXPIRE_PASSWD + $ADS_UF_PASSWD_CANT_CHANGE
$user.SetInfo()
#Add the account to the local admins group
$group = ([ADSI]"WinNT://$computer/$local_security_group,group")
$username = [ADSI]"WinNT://$Computer/$username,user"
#Validate whether user account has been created or not
$users = $comp.psbase.children | select -expand name
if ($users -like $username) {
Write-Host "$username has been created on $computer"
} else {
Write-Host "$username has not been created on $computer"
}
}
}
Catch {
Write-Host "Error creating $username on $($computer.path): $($Error[0].Exception.Message)"
}
}
In your code you are not actually adding the user to the group.
Here you are actually retrieving a group object, but you are not doing anything with it.
#Add the account to the local admins group
$group = ([ADSI]"WinNT://$computer/$local_security_group,group")
$username = [ADSI]"WinNT://$Computer/$username,user"
First you must remove the assignment to $username. Then you must invoke a method on the $group object to add the user:
#Add the account to the local admins group
$group = ([ADSI]"WinNT://$computer/$local_security_group,group")
$computerHostName = (Get-WmiObject -ComputerName $computer Win32_ComputerSystem).Name
$group.Add([ADSI]"WinNT://$computerHostName/$username,user")
There is a catch here. Notice I use Get-WmiObject to get the hostname from the computer. When using the Add() method, the computer name must be the unqualified hostname. For example server-01, and NOT server-01.domain.lan
If you want to retrieve the ADSI object for the user later, I recommend assigning it to a different variable name, like this:
$adsiUser = [ADSI]"WinNT://$Computer/$username,user"
I want to free up some C Drive space on my servers by removing user profiles that from C:\users who haven't logged into the server in the last 6 months. I connect to the servers using PowerShell Cim commands.
So far I have only found the Get-CimInstance -CimSession $CimSession -ClassName Win32_UserProfile command that will list users profiles but it doesn't list the last logon time for each user. Is there another command that can be used to list UserProfiles with LastLogon? Once I have that list I want to delete any profile that hasn't logged into the server in the last 6 months.
How to delete user profiles older than a specified number of days in Windows
This PowerShell script sample shows how to delete user profiles older than a specified number of days.
Example 1:
C:\Script\RemoveLocalUserProfile.ps1 -ListUnusedDay 1
Example 2:
C:\Script\RemoveLocalUserProfile.ps1 -DeleteUnusedDay 1 -ExcludedUsers “marry”
# Begin Script
If ($ProfileInfo -eq $null)
{
Write-Warning -Message "The item not found."
}
Else
{
Foreach ($RemoveProfile in $ProfileInfo)
{
#Prompt message
$Caption = "Remove Profile"
$Message = "Are you sure you want to remove profile '$($RemoveProfile.LocalPath)'?"
$Choices = [System.Management.Automation.Host.ChoiceDescription[]]`
#("&Yes", "&No")
[Int]$DefaultChoice = 1
$ChoiceRTN = $Host.UI.PromptForChoice($Caption, $Message, $Choices, $DefaultChoice)
Switch ($ChoiceRTN)
{
0
{
Try {$RemoveProfile.Delete(); Write-Host "Delete profile '$($RemoveProfile.LocalPath)' successfully."}
Catch {Write-Host "Delete profile failed." -ForegroundColor Red}
}
1 {break}
}
}
$ProfileInfo|Select-Object #{Expression = {$_.__SERVER}; Label = "ComputerName"}, `
#{Expression = {$_.ConvertToDateTime($_.LastUseTime)}; Label = "LastUseTime"},`
#{Name = "Action"; Expression = {If (Test-Path -Path $_.LocalPath)
{"Not Deleted"}
Else
{"Deleted"}
}
}
}
# End Script
Similar approaches can be see here:
https://community.spiceworks.com/how_to/124316-delete-user-profiles-with-powershell
https://www.business.com/articles/powershell-manage-user-profiles
Take care when deleting profiles, you don't want to hit machine special accounts. The Win32_UserProfile class has a LastUseTime property you can rely on.
$session = New-CimSession -ComputerName $cn
$gcimParams = #{
'CimSession' = $session
'ClassName' = 'Win32_UserProfile'
'Filter' = 'RefCount<1 and Special="false" and Loaded="false"'
}
$profileList = (Get-CimInstance #gcimParams).Where{$PSItem.LastUseTime -lt (Get-Date).AddMonths(-6)}
foreach ($user in $profileList)
{
$user | Remove-CimInstance -CimSession $session
}
I am trying to create user on remote machine using Powershell. Once account created I want to add that in local admin group.
Account is getting created but it is not getting added in admin group. Below is the code that I am using.
cls
$username = "test_user"
$password = "password"
$computer1 = hostname
$users = $null
$computer = [ADSI]“WinNT://$computer1”
Try {
$users = $computer.psbase.children | select -expand name
if ($users -like $username) {
Write-Host "$username already exists"
} Else {
$user_obj = $computer.Create(“user”, “$username”)
$user_obj.SetPassword($password)
$user_obj.SetInfo()
$user_obj.Put(“description”, “$username”)
$user_obj.SetInfo()
$user_obj.psbase.invokeset(“AccountDisabled”, “False”)
$user_obj.SetInfo()
$users = $computer.psbase.children | select -expand name
if ($users -like $username) {
Write-Host "$username has been created on $($computer.name)"
$group = [ADSI]("WinNT://"+$env:COMPUTERNAME+"/administrators,group")
$group.add("WinNT://$env:localhost/$username,user")
} Else {
Write-Host "$username has not been created on $($computer.name)"
}
}
} Catch {
Write-Host "Error creating $username on $($computer.path): $($Error[0].Exception.Message)"
}
What am I doing wrong?
$env:computername is your local computer. $env:localhost doesn't exist. $computer1 is the variable you defined of the computer to you are adding the user to earlier.
$group = [ADSI]("WinNT://$computer1/administrators,group")
$group.add("WinNT://$computer1/$username,user")
I use this
$computername = "computername" # place computername here for remote access
$username = 'user'
$password = 'P#ssw0rd1' #password
$desc = 'Local admin account'
$computer = [ADSI]"WinNT://$computername,computer"
$user = $computer.Create("user", $username)
$user.SetPassword($password)
$user.Setinfo()
$user.description = $desc
$user.setinfo()
$user.UserFlags = 65536
$user.SetInfo()
$group = [ADSI]("WinNT://$computername/administrators,group")
$group.add("WinNT://$username,user")
That is a whole lot of code, just to do this.
Invoke-Command -ComputerName SomeRemoteComputerName -ScriptBlock {
net user SomeNewUserName SomePassword
net localgroup administrators SomeNewUserName /add
}
Yeppers, I know, it's not all pure PoSH. Sure, you can do this with via more code in PoSH (way more in ), but sometimes you just need to get stuff done.
But vs doing this from scratch (well, unless you are just trying to learn stuff). There is a whole set of pre-built scripts and module for you to leverage. See:
'gallery.technet.microsoft.com/scriptcenter/site/search?f%5B0%5D.Type=RootCategory&f%5B0%5D.Value=localaccount'
Of course if all machines were on PoSH v5+, then you just use the built-in cmdlets for local user / group management.
'learn.microsoft.com/en-us/powershell/module/microsoft.powershell.localaccounts/?view=powershell-5.1'
As for the other question:
'check service account exist or not'
Assuming you are asking if this is for a remote computer, then it's the same approach.
Invoke-Command -ComputerName SomeRemoteComputerName -ScriptBlock {
Get-Service -Name SomeServiceName
Get-Service -DisplayName SomeServiceDisplayName
}