user to see Terms and conditions screen at password change - powershell

The company I am working for would like a splash screen that I did to pop up when ever a user changes password (90 day rule at present), this is mainly due to a external requirement.
One of the snags I have is that the system has no email to show me that a user is expiring, I am looking at a couple of things
A log output of expired accounts and locked accounts, ignoring accounts not logged on disabled accounts system etc.
On the 90 day policy a splash screen pops up with the t$c with an accept or decline window (they see this when they first turn the PC and pops up just before the logon box on basically saying by accepting you agree to have read blah and blah)
I do not know how to get either this to run as one script or have two separate scripts,
Any input greatly appreciated
Import-Module ActiveDirectory # Required for PowerShell 2.0 only
$a = (Get-Date).Date.AddDays(-89)
# The following line will build the variable based upon the noted criteria
$b = Get-ADUser `
-Property Name, SamAccountName, PasswordLastSet, CannotChangePassword, PasswordNeverExpires `
-Filter { (PasswordLastSet -lt $a) -and (PasswordNeverExpires -eq $false) } |
Where-Object { $_.CannotChangePassword -eq $false }
# The following line will display/export the data logging the accounts to be changed
# please note the Out-File path and change to suit your needs.
$b | Format-Table Name, PasswordLastSet, CannotChangePassword, PasswordNeverExpires -AutoSize |
Out-File -FilePath "C:\passwordchanges.txt"
# The following line will actually flag the accounts to require a password change
# (after -WhatIf is removed)
$b.SamAccountName | ForEach-Object {
Set-ADUser -Identity $_ -ChangePasswordAtLogon $true -WhatIf
}

Related

Enabling Exchange Online SMTP Client Authentication with Powershell

I'm trying to enable Authenticated SMTP in Exchange Online via PowerShell.
I was semi successful with my attempts.
$Users = Get-CASMailbox -ResultSize unlimited
$Users | where {$_.SmtpClientAuthenticationDisabled -eq $true} | Set-CASMailbox -SmtpClientAuthenticationDisabled $False
This resulted in about 75% of the users having SMTP Authentication activated. But weirdly not all of them.
$Users = Get-CASMailbox -ResultSize unlimited
$Users | where {$_.SmtpClientAuthenticationDisabled -eq $true -or $null -or ""} | Set-CASMailbox -SmtpClientAuthenticationDisabled $False
Showed the same results.
As did:
$Users = Get-CASMailbox -ResultSize unlimited
$Users | where {$_.ImapEnabled -eq $true} | Set-CASMailbox -SmtpClientAuthenticationDisabled $False
So apparently this has nothing to do with the state of SmtpClientAuthenticationDisabled since I tried all possible states and used ImapEnabled -eq $true as a condition which is $true for every user.
I just started working with PowerShell and only have some basic programming knowledge. This setting has to be changed for about 80 accounts right now, but in a week or two about 4000 accounts will be synchronized with AzureAD and therefore Exchange Online. So far I haven't received an answer from the company which synchronizes the accounts on wether or not it's possible to set the state of SmtpClientAuthenticationDisabled when the synchronization happens. I expect that I will have to do it myself.
All users have an active Office 365 Licence and an active Exchange Online Plan.
Does anyone have some insight as to why only most but no all of the users accept this setting?
Edit:
When trying to execute your suggested script or when trying to execute my own commands I run into the issue that '$user' returns '$null' which I don't understand.
Setting SmtpClientAuthenticationDisabled for failed, error: Cannot bind argument to parameter 'Identity' because it is null.
This also happens when im only executing this:
$Users = Get-CASMailbox -ResultSize Unlimited
foreach($user in $users) {Write-Host "$($user.DisplayName)"}
It just returns nothing.
I think there is something fundamental that I don't understand.
If I just list the contents of '$users' PowerShell returns a list of all the users with the related settings like 'SmtpClientAuthenticationDisabled'.
If you want your complete organization to use the same setting, you should leave the values of the users $null. Instead set the TransportConfig.
Get-TransportConfig
Then check the value. If it is set to 'False', all users with a $null-value for SmtpClientAuthenticationDisabled will have the default setting of 'False'.
If set to 'True', change to 'False' instead:
Set-TransportConfig -SmtpClientAuthenticationDisabled $false
To answer your original question, of why the users are not updated properly. I think it has something to do with the fact that 'SmtpClientAuthenticationDisabled' is not a filterable attribute in the first place. So you will always have to query your complete dataset, which is not very elegant.
You could do something like the following to check and see what happens exactly:
$Users = Get-CASMailbox -ResultSize Unlimited
foreach($user in $Users){
if($user.SmtpClientAuthenticationDisabled -eq $null -or $user.SmtpClientAuthenticationDisabled -eq $true){
try{
Set-CASMailbox -Identity $user.ExchangeObjectId.guid -SmtpClientAuthenticationDisabled $false -ErrorAction Stop
Write-Host "$($user.DisplayName) succesfully set to correct state" -ForegroundColor Green
}catch{
Write-Host "Setting SmtpClientAuthenticationDisabled for $($user.DisplayName) failed, error: $_" -ForegroundColor Red
}
}else{
Write-Host "$($user.DisplayName) already has the correct state: $($user.SmtpClientAuthenticationDisabled)" -ForegroundColor Green
}
}
But personally I would change the above script to use it to set all values to $null:
Set-CASMailbox -Identity $user.ExchangeObjectId.guid -SmtpClientAuthenticationDisabled $null -ErrorAction Stop

Log each Powershell process to text file through

Firstly, I'm by no means a PS expert, total newbie - admission done. I have scoured the internet for what I need in order to get the script to do what I want, but I've reached a point where I'm struggling and in need of help.
Basically, I've created a script using ISE that grabs the users in an AD OU, processes them by disabling the accounts, renaming them, stripping out the groups and moving them to another folder. In order to automate the deactivation process for users. But I now need to create a log file every time this runs, to show a) if it found any Users in the original OU (ToBeProcessed) and b) what processes were run and if they were successful. Here is the code.
$OUToBeProcessed = "OU=ToBeProcessed,OU=Users,OU=World,DC=local"
$OURetired = "OU=RetiredUsers,OU=Users,OU=World,DC=local"
$Users = Get-ADUser -SearchBase $OUToBeProcessed -Filter 'name -Like "*"' -Properties MemberOf
ForEach($User in $Users){
$SAN = $User.SamAccountName
#Disable user account
Disable-ADAccount -Identity $SAN
#Remove membership from groups for user
$User.Memberof | Remove-ADGroupMember -Member $User -Confirm:$False
$NewDN = "zzz_" + $User.Name
#Change display name
set-aduser $User -Displayname $newDN -ErrorAction SilentlyContinue
#Change distinguished name
Get-ADUser $SAN | Rename-ADObject -Newname $NewDN
Write-Host "$SAN may already exist."
#Move account to RetiredUsers
Get-Aduser $SAN | Move-ADObject -TargetPath $OURetired
}
I'm assuming I'll need to either use a Write-Output or Log-File cmdlet, though someone had also suggested Transcript, but I don't think that's what I need.
I've tried a number of ways to incorporate the Write-Output into the script, it runs without errors, but no text file is produced. But I'm placing it within the loop which may be the issue. I've placed it outside the loop but I think because it's not being passed anything it's creating the file with nothing in it. Would really appreciate some help as to where the Write-Output might need to go if that is the right cmdlet.
Personally I tend to add a Log function to my scripts. Something like this (where I output to the host and file):
Function Log {
Param (
[Parameter(Mandatory=$true)] [string] $String,
[Parameter(Mandatory=$true)] [string] $LogFilePath,
[Parameter(Mandatory=$false)][ValidateSet("ERROR","WARN","INFO","DEBUG")] [string] $Level = "INFO"
)
$LogString = ((Get-Date -Format "s") +" $Level $env:USERNAME $String")
Write-Host $LogString
Out-File -Append -FilePath $LogFilePath -InputObject $LogString
}
Then you could do logging:
Log "Something wrong!" "c:\mylog.log" "WARN"
Log "Updated stuff" "c:\mylog.log"
Or search the http://www.powershellgallery.com/ for logging modules.
Example (haven't tried this one myself):
https://www.powershellgallery.com/packages/PSLogging/2.5.2

Remove full access permissions of all disabled users on shared mailboxes with exchange management shell

I’m looking for a powershell exchange script to remove Full access permissions of all disabled users on all shared mailboxes in a specific OU.
This is what I got so far
Remove-MailboxPermission -Identity Sharedmailbox -AccessRights Fullaccess -InheritanceType all -user DisabledUser -Confirm:$false | where {$_.UseraccountControl -like "*accountdisabled*"}
Its seems to work but I’m not sure about the last piece of het script if it will check for “accountdisabled”
Then I created a variable so it will check only one specific OU
$ou = Get-ADUser -SearchBase "OU=Functional Mailboxes,OU=Generalaccounts,DC=DOMAIN,DC=COM" -Filter * foreach ($user in $ou)
Remove-MailboxPermission -Identity "$ou" -AccessRights Fullaccess -InheritanceType all -Confirm:$false | where {$_.UseraccountControl -like "*accountdisabled*"}
The script is checking the right OU but I'm still looking for the last part where it will automatically remove full access permissions of the disabled users ONLY.
Can someone show me the way?
Instead of trying to screen for disabled users after removing the mailbox permissions (which is what your Remove-MailboxPermission ... | Where-Object ... appears to be intended to do - except that the way you wrote it, it's only checking for disabled state after removing the permissions), try selecting for the disabled accounts first, then passing only the disabled accounts to Remove-MailboxPermission:
Get-ADUser -SearchBase ... -filter {Enabled -eq $false} | Remove-Mailbox ...
(replacing ... with the appropriate SearchBase or parameters for Remove-Mailbox, using $_ for the identity of the ADUser whose mailbox permissions you're removing.)

Finding current logged on user(s) while running as SYSTEM (no environment variables)

I have created a PowerShell script that saves the current user to a report. When creating this report, it was working fine because I was using $env:USERNAME. However, now that the report is running under the SYSTEM account as a scheduled task, it saves the current user as "HOSTNAME$." Is there another easy way of getting the logged on users? The following doesn't work as well:
Get-WMIObject -class Win32_ComputerSystem | select username
Any ideas would be greatly appreciated as I need the current logged on user saved. I also need to run the report as NT AUTHORITY\SYSTEM to run the elevated tasks.
"Current user" is an ambiguous term that depends on what you're looking at. A user logged in on the desktop (locally or remotely)? A user running a background process? A user accessing an SMB share? WMI? WinRS?
Assuming that you want to identify which user is logged in on the desktop, you could check the owner of the explorer.exe process as described in this answer on ServerFault:
Get-WmiObject Win32_Process -Filter "Name='explorer.exe'" |
ForEach-Object { $_.GetOwner() } |
Select-Object -Unique -Expand User
I was able to gather the current logged on user by using tasklist in PowerShell:
$User = tasklist /v /FI "IMAGENAME eq explorer.exe" /FO list | find "User Name:"
$User = $User.Substring(14)
Works perfectly even when ran as SYSTEM.
I know this is old, it took me all morning to get this straightened out, this gets you the current logged on user and their my docs path, since environment variables don't work under the system account.
New-PSDrive HKU Registry HKEY_USERS
$user = get-wmiobject -Class Win32_Computersystem | select Username;
$sid = (New-Object System.Security.Principal.NTAccount($user.UserName)).Translate([System.Security.Principal.SecurityIdentifier]).value
$val = (Get-Item "HKU:\$sid\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders");
$myDocPath = $val.GetValue("Personal");
To test using a powershell account that runs as system, follow these instructions
http://powershell-guru.com/powershell-tip-53-run-powershell-as-system/
Assuming from your original script that you are looking to return just usernames, you could use this:
Get-Process -IncludeUserName | Select-Object UserName -Unique |
Where-Object {$.UserName -notlike 'NT AUTHORITY\SYSTEM' -and
$.UserName -notlike 'NT AUTHORITY\NETWORK SERVICE' -and $_.UserName
-notlike 'NT AUTHORITY\LOCAL SERVICE'} | Format-Table -Wrap -AutoSize
I liked the Get-Process answer from #MNiles, but made it a little simpler with the filtering for explorer from the other answers
Get-Process -IncludeUserName -Name explorer | Select-Object UserName -Unique

Powershell command to hide user from exchange address lists

I'm trying to write powershell script which hides user from exchange lists.
I was able to find following command:
Set-Mailbox -Identity [user id here] -HiddenFromAddressListsEnabled $true
And it doesn't give me an error message, and when I run the command twice, I get following warning:
WARNING: The command completed successfully but no settings of '[user id here]' have been modified.
Which probably means that the command did actually work.
but when I go to Exchange Management Console, and open user profile, "hide user from exchange address lists" check box is off.
What could be the reason?
I use this as a daily scheduled task to hide users disabled in AD from the Global Address List
$mailboxes = get-user | where {$_.UserAccountControl -like '*AccountDisabled*' -and $_.RecipientType -eq 'UserMailbox' } | get-mailbox | where {$_.HiddenFromAddressListsEnabled -eq $false}
foreach ($mailbox in $mailboxes) { Set-Mailbox -HiddenFromAddressListsEnabled $true -Identity $mailbox }
You can use the following script, just replace DOMAIN with the name of your domain. When executed it will prompt you for a userlogin then hide that user's account from the address lists.
$name=Read-Host "Enter login name of user to hide"
Set-Mailbox -Identity DOMAIN\$name -HiddenFromAddressListsEnabled $true
Brian.
I was getting the exact same error, however I solved it by running $false first and then $true.
You will have to pass one of the valid Identity values like DN, domain\user etc to the Set-Mailbox cmdlet. Currently you are not passing anything.
"WARNING: The command completed successfully but no settings of '[user id here]' have been modified."
This warning means the setting was already set like what you want it to be. So it didn't change anything for that object.
For Office 365 users or Hybrid exchange, go to using Internet Explorer or Edge, go to the exchange admin center, choose hybrid, setup, chose the right button for hybrid or exchange online.
To connect:
Connect-EXOPSSession
To see the relevant mailboxes:
Get-mailbox -filter {ExchangeUserAccountControl -eq 'AccountDisabled'
-and RecipientType -eq 'UserMailbox' -and RecipientTypeDetails -ne 'SharedMailbox' }
To block based on the above idea of 0KB size:
Get-mailbox -filter {ExchangeUserAccountControl -eq 'AccountDisabled'
-and RecipientTypeDetails -ne 'SharedMailbox' -and RecipientType -eq 'UserMailbox' } | Set-Mailbox -MaxReceiveSize 0KB
-HiddenFromAddressListsEnabled $true