I am fairly new to PowerShell and this maybe straight forward for a professional.
I am looking to extend expiration date a bulk of AD usernames in a text file by 6 months.
Preferably if the code could pick up the current date and extend from there.
As I have been doing some googling and testing I am come up with the command to do a single account in PowerShell:
Set-ADAccountExpiration SMahmood -DateTime "06/11/2022"
The above command I obviously have to change the username and date (if I run the command on different day) every time I run the command.
I have also managed to find some script of another person who asked a similar question but his script asks you to define the username each time you would like to extend it (this is not my code but has been tested as working) :
$continue = $true
while ($continue) {
write-host " AD Account Expiration Date Changer" -ForegroundColor White
Write-Host ""
while ($true) {
try {
# Loop until a valid username is entered
$Entered_Username_0 = Read-Host "Enter a username"
$Entered_Username = $Entered_Username_0.Trim()
if (Get-ADUser -Identity $Entered_Username | Out-Null) {
throw
}
break
}
catch {
Write-Host ""
Write-Host "Invalid username entered!" -ForegroundColor Red
Write-Host ""
}
}
$dateMin = [datetime]::Now
$dateMin_short = $dateMin.ToShortDateString()
Write-Host "Press 1 to extend the account expiration date by 6 months"
Write-Host "Press 2 to extend the account expiration date to a sprecific date"
$Choice_input = Read-Host "Please select an option"
while ($true) {
try {
if ($Choice_input -eq 2) {
while ($true) {
try {
# Loop until a valid Date is entered and that Date is above $dateMin
$Entered_Date = [datetime]::ParseExact(
(Read-Host "Enter a new expiry date, in the format DD/MM/YYYY"),
'dd/MM/yyyy',
[System.Globalization.CultureInfo]::new('en-GB')
)
if ($Entered_Date -lt $dateMin) {
throw
}
break
}
catch {
Write-Host ""
Write-Host "Invalid date entered! Format must be DD/MM/YYYY and higher than $dateMin_short." -ForegroundColor Red
Write-Host ""
}
}
}
if ($Choice_input -eq 1) {
$Entered_Date = [datetime]::Now.addmonths(6)
}
else {
throw
}
break
}
catch {
Write-Host ""
Write-Host "Please input a either 1 or 2." -ForegroundColor Red
Write-Host ""
}
}
try {
Set-ADAccountExpiration -Identity $Entered_Username -DateTime $Entered_Date.AddHours(24)
Write-Host ""
Write-Host "New account expiration date for $Entered_Username is $(($Entered_Date).toString('dd/MM/yyyy'))"-ForegroundColor Green
$Entered_Date = ($Entered_date).toString('dd/MM/yyyy')
}
catch {
Write-Host ""
Write-Host "Unable to set account expiry: $_"-ForegroundColor Red
}
Write-Host ""
}
$continue = $true
while ($continue) {
write-host " AD Account Expiration Date Changer" -ForegroundColor White
Write-Host ""
while ($true) {
try {
# Loop until a valid username is entered
$Entered_Username_0 = Read-Host "Enter a username"
$Entered_Username = $Entered_Username_0.Trim()
if (Get-ADUser -Identity $Entered_Username | Out-Null) {
throw
}
break
}
catch {
Write-Host ""
Write-Host "Invalid username entered!" -ForegroundColor Red
Write-Host ""
}
}
$dateMin = [datetime]::Now
$dateMin_short = $dateMin.ToShortDateString()
Write-Host "Press 1 to extend the account expiration date by 6 months"
Write-Host "Press 2 to extend the account expiration date to a sprecific date"
$Choice_input = Read-Host "Please select an option"
while ($true) {
try {
if ($Choice_input -eq 2) {
while ($true) {
try {
# Loop until a valid Date is entered and that Date is above $dateMin
$Entered_Date = [datetime]::ParseExact(
(Read-Host "Enter a new expiry date, in the format DD/MM/YYYY"),
'dd/MM/yyyy',
[System.Globalization.CultureInfo]::new('en-GB')
)
if ($Entered_Date -lt $dateMin) {
throw
}
break
}
catch {
Write-Host ""
Write-Host "Invalid date entered! Format must be DD/MM/YYYY and higher than $dateMin_short." -ForegroundColor Red
Write-Host ""
}
}
}
if ($Choice_input -eq 1) {
$Entered_Date = [datetime]::Now.addmonths(6)
}
else {
throw
}
break
}
catch {
Write-Host ""
Write-Host "Please input a either 1 or 2." -ForegroundColor Red
Write-Host ""
}
}
try {
Set-ADAccountExpiration -Identity $Entered_Username -DateTime $Entered_Date.AddHours(24)
Write-Host ""
Write-Host "New account expiration date for $Entered_Username is $(($Entered_Date).toString('dd/MM/yyyy'))"-ForegroundColor Green
$Entered_Date = ($Entered_date).toString('dd/MM/yyyy')
}
catch {
Write-Host ""
Write-Host "Unable to set account expiry: $_"-ForegroundColor Red
}
Write-Host ""
}
Big thanks Vihaan Reyansh who provided the script above I had to tweak it a bit as it was changing the description field.
Related
I am trying to add a user to the Remote Desktop group using Powershell.
It seems it's not breaking the loop and doesn't execute further statements.
Can you please help me where the issue is:
$remote = ""
While($remote -ne "Y" ){
$remote = read-host "Do you need to add anyone to the Remote Desktop group (y/n)?"
Switch ($remote)
{
Y {
$remoteuser = ""
while ( ($remoteuser -eq "") -or ($UserExists -eq $false) )
{
$remoteuser = Read-Host "Enter the username that needs to be in the group"
Write-Host "User inputted $remoteuser"
sleep -Seconds 2
try {
Get-ADUser -Identity $remoteuser -Server <server-FQDN>
$UserExists = $true
Write-Host "$remoteuser found!"
sleep 5
}
catch [Microsoft.ActiveDirectory.Management.ADIdentityResolutionException] {
Write-Host "User does not exist."
$UserExists = $false
}
catch {
Write-Host "Username is blank"
$UserExists = $false
}
}
}
N {Write-Host "No user accounts will be added to the Remote Desktop Users group. Restart your PC."}
default {Write-Host "Only Y/N are Valid responses"}
}
}
<further statements>
I am creating a new column called "TEST123" which is a Person Or Group and wanted to also update "Choose from" option from All users to SP group called TESTAccounts.
I have got the following script to create the column but not sure how to make the above changes :
Function Add-FieldToList($SiteURL,$ListName, $FieldName, $FieldType, $IsRequired){
$ErrorActionPreference = "Stop"
Try{
$List = (Get-SPWeb $SiteURL).Lists.TryGetList($ListName)
if($List -ne $null)
{
if(!$List.Fields.ContainsField($FieldName))
{
$List.Fields.Add($FieldName,$FieldType,$IsRequired)
$List.Update()
$View = $List.DefaultView # OR $List.Views["All Items"]
$View.ViewFields.Add($FieldName)
$View.Update()
write-host "New Column '$FieldName' Added to the List!" -ForegroundColor Green
}
else
{
write-host "Field '$FieldName' Already Exists in the List" -ForegroundColor Red
}
}
else
{
write-host "List '$ListName' doesn't exists!" -ForegroundColor Red
}
}
catch {
Write-Host $_.Exception.Message -ForegroundColor Red
}
finally {
$ErrorActionPreference = "Continue"
}
}
$SiteURL="http://TESTURL"
$ListName = "NEWList"
$FieldType = [Microsoft.SharePoint.SPFieldType]::User
$FieldName="TEST123"
$IsRequired = $False
Add-FieldToList $SiteURL $ListName $FieldName $FieldType $IsRequired
You could use the follow powershell set people column choose from certain group:
$SPSite = Get-SPSite 'http://sp'
#Open you web
$OpenWeb = $SpSite.OpenWeb();
#Open Your List
$List = $OpenWeb.Lists["test2"];
$column = $list.Fields["user"]#change to your column name
$column.SelectionGroup=15 #group id you want
$column.Update()
I have been able to create an array and store a list of fields, I am trying to convert this to a CSV file. However, I need all my outputs to be as a string. Currently I have text coming out as a string, however for example I need my note to come out as a string but it comes out as taxonomy value and not sure how to change this?
Below is my code I have just now:
# Get the web
$web = Get-SPWeb "specified_website"
# Get the target list
$list = $web.Lists["List_name"]
# Items used to hold the data
$Items = $list.Items
$array = #()
# Get all the items in the list
foreach ($item in $Items) {
$id = $item.id
Write-Host "Processing item number $id" -ForegroundColor Green
# every item has a Field e.g. my item has a title, etc.
foreach ($field in $item.Fields) {
# Get the type of the field
Write-Host $field.Type
# Print the field type out to a string
switch ($field.Type) {
"Text" { $msg = checkifTextisNull($item[$field.InternalName]) }
"Note" {
Write-Host $item[$field.InternalName] -ForegroundColor Cyan
}
"Lookup" { $item[$field.InternalName] -ForegroundColor Yellow }
"URL" { Write-Host $item[$field.InternalName] -ForegroundColor Magenta }
"Invalid" {
#Write-Host $item[$field.InternalName] -ForegroundColor Cyan
}
"Guid" { Write-Host $item[$field.InternalName]-ForegroundColor Yellow }
"Choice" { Write-Host $item[$field.InternalName] -ForegroundColor Cyan }
"Boolean" {
$msg = returnBooleanValue($item[$field.InternalName])
Write-Host $msg -ForegroundColor DarkCyan
}
"Computed" { Write-Host $item[$field.InternalName] -ForegroundColor White }
"Integer" {
Write-Host $item[$field.InternalName]
}
"User" { Write-Host $item[$field.InternalName] -ForegroundColor DarkGreen }
"DateTime" {
Write-Host $item[$field.InternalName] -ForegroundColor DarkGreen
}
"Number" { Write-Host $item[$field.InternalName] -ForegroundColor Yellow }
"Counter" { Write-Host $item[$field.InternalName] -ForegroundColor Green }
"Multi-Choice" {
Write-Host $item[$field.InternalName]
}
"Attachments" { Write-Host $item[$field.InternalName] -ForegroundColor Magenta }
"ModStat" { Write-Host $item[$field.InternalName] -ForegroundColor DarkGreen }
"File" { Write-Host $item[$field.InternalName] -ForegroundColor White }
}
}
# Add the object with property to Items
$array += $Items
}
My output that I get is:
Note
Firm wide|0d3fbace-af9c-4f28-8be1-095e616893c0
And the Output I would expect is:
"FieldName", "DataType", "Value"
Site_type_0, Note , Firm Wide
When I Write out what the type of data is, I get taxonomy data, when I would want a string
I found that using .TypeAsString helped me out a lot and for the TaxonomyFieldType and TaxonomyFieldTypeMulti Field types I done the following:
"TaxonomyFieldType"{
$FieldValue = $item[$field.InternalName] -as [Microsoft.SharePoint.Taxonomy.TaxonomyFieldValue];
$FieldValue = $FieldValue.Label;
$FieldValue
}
"TaxonomyFieldTypeMulti"{$FieldValueCollection = $item[$field.InternalName] -as [Microsoft.SharePoint.Taxonomy.TaxonomyFieldValueCollection];
foreach($Value in $FieldValueCollection) {
if($Value.label -ne $null)
{
$label = $Value.label
$guid = $Value.TermGuid.ToString()
$FieldValue+="Label = $label Guid = $guid;"
}
}
Write-Host $Value.label
}
If there is anyone who knows a better way please let me know as I would be very interested to hear.
I want to jump from one section in the script to another section in the same PowerShell script. My script is only going from top to bottom right now, but I have several tasks. e.g. I want to be able to choose from a task list in the beginning of the script and go to task number 2 skip task 1.
I hope this makes any sense for you. Take a look at my script:
Write-Host -ForegroundColor Yellow "welcome to my powershell script..."
""
""
""
Start-Sleep -Seconds 1
Write-Host -ForegroundColor Yellow "Choose a task:"
""
""
Write-Host -ForegroundColor Yellow "1. Clean up"
Write-Host -ForegroundColor Yellow "2. Uninstall Pre-Installed Apps"
Write-Host -ForegroundColor Yellow "3. Something should be written here"
""
""
""
While ($Valg -ne "1" -or $Valg -ne "2" -or $Valg -ne "3") {
$Valg = Read-Host "Choose a number from the task list"
If ($Valg –eq "1") { Break }
If ($Valg –eq "2") { Break }
If ($Valg –eq "3") { Break }
if ($Valg -ne "1" -or $Valg -ne "2" -or $Valg -ne "3") {
""
Write-Host -ForegroundColor Red "Ups. Try again..."
}
}
#### 1. First task should come here (clean up)
#some code here for the "cleaning up" task
#### 2. Second task here
#some code here for the "Uninstall Pre-Installed Apps" task
#### 3. Third task there
#Some code for the third task here
#### And so on...
Here is a generic solution which uses an array of PSCustomObject that represents the task (message and the function to invoke). It doesn't need a switch, you can simply add new Tasks to the array (and implement the desired function) without modifying the remaining script:
# define a task list with the messages to display and the functions to invoke:
$taskList = #(
[PSCustomObject]#{Message = 'Clean up'; Task = { Cleanup }}
[PSCustomObject]#{Message = 'Uninstall Pre-Installed Apps'; Task = { Uninstall }}
[PSCustomObject]#{Message = 'Something should be written here'; Task = { Print }}
)
# define the functions:
function Cleanup()
{
Write-Host "Cleanup"
}
function Uninstall()
{
Write-Host "Uninstall"
}
function Print()
{
Write-Host "Print"
}
# let the user pick a task:
Write-Host -ForegroundColor Yellow "Choose a task:"
$taskList | foreach -Begin { $i = 1;} -Process {
Write-Host -ForegroundColor Yellow ('{0}. {1}' -f ($i++), $_.Message)
}
do
{
$value = Read-Host 'Choose a number from the task list'
}
while($value -match '\D+' -or $value -le 0 -or $value -gt $taskList.Count)
# invoke the task:
& $taskList[$value-1].Task
I am updating answer to complete script based on inputs by "bluuf" and "majkinator".
Use the Switch-Case construct along with Functions like below. This is complete working solution.
#region Function Definitions. These come first before calling them
function FirstTask
(
[string] $inputVariable
)
{
"write any scipt for First task here without quotes. Input is: " + $inputVariable
}
function SecondTask
{
"write any scipt for Second task here without quotes"
}
function ThirdTask
{
"write any scipt for Third task here without quotes"
}
#endregion
#region Showing Options
Write-Host -ForegroundColor Yellow "welcome to my powershell script..."
""
""
""
Start-Sleep -Seconds 1
Write-Host -ForegroundColor Yellow "Choose a task:"
""
""
Write-Host -ForegroundColor Yellow "1. Clean up"
Write-Host -ForegroundColor Yellow "2. Uninstall Pre-Installed Apps"
Write-Host -ForegroundColor Yellow "3. Something should be written here"
Write-Host -ForegroundColor Yellow "0. Exit"
""
""
""
#endregion
#region Getting input
While ($true) {
$Valg = Read-Host "Choose a number from the task list"
If ($Valg –eq "0")
{
"Thanks for using my utility";
Break;
}
If (($Valg -ne "1") -and ($Valg -ne "2") -and ($Valg -ne "3") -and ($Valg -ne "0")) {
""
Write-Host -ForegroundColor Red "Ups. Try again..."
}
#region Main Code
switch ($Valg)
{
1{
FirstTask("sending input");
}
2 {
SecondTask;
}
3 {
ThirdTask;
}
default { "Please select a correct option."}
}
#endregion
}
#endregion
I'm a Powershell newb, but I am trying to write a script to check the SSL certificate expiration dates for multiple remote websites.
I found this script (http://www.zerrouki.com/checkssl/) that does what I want, but only for a single site.
I am trying to modify it to allow for multiple sites/checks, but am getting an error when I do so. I've removed all of the email functionality from the script as I'll be using another to tool to alert on expiring certs. And I've hardcoded the URLs to check.
<#
Modified from Fabrice ZERROUKI - fabricezerrouki#hotmail.com Check-SSL.ps1
#>
$WebsiteURLs= #("URL1.com","URL2.com","URL3.com")
$WebsitePort=443
$CommonName=$WebsiteURL
$Threshold=120
foreach ($WebsiteURL in $WebsiteURLs){
Try{
$Conn = New-Object System.Net.Sockets.TcpClient($WebsiteURL,$WebsitePort)
Try {
$Stream = New-Object System.Net.Security.SslStream($Conn.GetStream())
$Stream.AuthenticateAsClient($CommonName)
$Cert = $Stream.Get_RemoteCertificate()
$ValidTo = [datetime]::Parse($Cert.GetExpirationDatestring())
Write-Host "`nConnection Successfull" -ForegroundColor DarkGreen
Write-Host "Website: $WebsiteURL"
$ValidDays = $($ValidTo - [datetime]::Now).Days
if ($ValidDays -lt $Threshold)
{
Write-Host "`nStatus: Warning (Expires in $ValidDays days)" -ForegroundColor Yellow
Write-Host "CertExpiration: $ValidTo`n" -ForegroundColor Yellow
}
else
{
Write-Host "`nStatus: OK" -ForegroundColor DarkGreen
Write-Host "CertExpiration: $ValidTo`n" -ForegroundColor DarkGreen
}
}
Catch { Throw $_ }
Finally { $Conn.close() }
}
Catch {
Write-Host "`nError occurred connecting to $($WebsiteURL)" -ForegroundColor Yellow
Write-Host "Website: $WebsiteURL"
Write-Host "Status:" $_.exception.innerexception.message -ForegroundColor Yellow
Write-Host ""
}
}
When I run this (with valid sites in the $WebsiteURLs variable) every site returns: Status: Authentication failed because the remote party has closed the transport stream.
If I only put one site in the $WebsiteURLs variable and remove the foreach function it runs ok.
Any idea what I can do to make this loop through each site in the variable?
Problem lies here:
$WebsiteURLs= #("URL1.com","URL2.com","URL3.com")
$WebsitePort=443
$CommonName=$WebsiteURL
When you call $Stream.AuthenticateAsClient($CommonName) it doesn't work, because $CommonName=$WebsiteURL is setting $commonName to null. When you remove the loop I assume you did as I did and changed $WebsiteURLs to $WebsiteURL so then you had a value to assign $CommonName.
If you move the declaration of $CommonName to within your loop it works.
$WebsiteURLs= #("URL1.com","URL2.com","URL3.com")
$WebsitePort=443
$Threshold=120
foreach ($WebsiteURL in $WebsiteURLs){
$CommonName=$WebsiteURL
Try{
$Conn = New-Object System.Net.Sockets.TcpClient($WebsiteURL,$WebsitePort)
Try {
$Stream = New-Object System.Net.Security.SslStream($Conn.GetStream())
$Stream.AuthenticateAsClient($CommonName)
$Cert = $Stream.Get_RemoteCertificate()
$ValidTo = [datetime]::Parse($Cert.GetExpirationDatestring())
Write-Host "`nConnection Successfull" -ForegroundColor DarkGreen
Write-Host "Website: $WebsiteURL"
$ValidDays = $($ValidTo - [datetime]::Now).Days
if ($ValidDays -lt $Threshold)
{
Write-Host "`nStatus: Warning (Expires in $ValidDays days)" -ForegroundColor Yellow
Write-Host "CertExpiration: $ValidTo`n" -ForegroundColor Yellow
}
else
{
Write-Host "`nStatus: OK" -ForegroundColor DarkGreen
Write-Host "CertExpiration: $ValidTo`n" -ForegroundColor DarkGreen
}
}
Catch { Throw $_ }
Finally { $Conn.close() }
}
Catch {
Write-Host "`nError occurred connecting to $($WebsiteURL)" -ForegroundColor Yellow
Write-Host "Website: $WebsiteURL"
Write-Host "Status:" $_.exception.innerexception.message -ForegroundColor Yellow
Write-Host ""
}
}