Okay – just ran across something VERY annoying with Win10

I could not get into my laptop’s BIOS or boot menu.

Not even from a power off.

Thanks Microsoft. Yes, they did it. And here’s how to undo it.

1] On the Start Menu go to Settings.
2] Go to System
3] Go to Power & sleep
4] On the right side, at the bottom, click Additional Power Settings.
5] Click Choose what the power buttons do on the left pane
6] Click Change settings that are currently unavailable, then scroll to the bottom and UNCHECK Turn on fast startup

Save your changes and you’ll be able to get to your BIOS and boot menu a=on the next reboot.

Advertisements
Comments Off on Okay – just ran across something VERY annoying with Win10 Posted in Uncategorized Tagged

Boy have I been away or what?

I’ve been seriously bad about keeping this up to date and I’m going to try to get it going again.

To start with I’m going to try to put forward some of the scripts I’ve written for work, sanitized of course to remove data. I’m also going to try to publish some about the things I’m doing outside of work. One of those is working on some new ‘saddle bags’ for my motorcycle.

Comments Off on Boy have I been away or what? Posted in Uncategorized

Interlude III : Setting Primary Group ID

Ran into an interesting situation at work today. An account had had the primary group changed from the Domain Users group to another group and then the Domain Users membership was removed. Needless to say, this caused some issues with an application that was granting rights based on membership to the Domain Users group. That got me thinking about how to set the primary group on an account without having to root around inside the ADUC utility.

Setting this is pretty simple from a PowerShell perspective. Fisrt we need to find the SID of our desired primary group. To do this we use the following:

$groupsid = (Get-ADGroup "group name").sid

This gets us the SID information in a variable where we can work with it. Notice I said “where we can work with it” versus just “in a variable”. If you look at the variable contents you’ll find we have more than just the SID.

[PS]>$groupsid | fl
BinaryLength : 28
AccountDomainSid : S-1-5-21-<SID stuff here>
Value         : S-1-5-21-<SID stuff here>-513

We actually have three values : the binary length, the domain SID the group is in, and the full SID of the group. We need to be concerned with only the Value, and specifically only with the last bit, 513. To get that portion we’re going to use two string functions – LastIndexOf and Substring. The LastIndexOf is going to give us the position of the last occurrence of the character “-” which comes just before the group ID (513). By adding one to that and using the Substring function we’ll be able to get everything to the right of that. We’ll place this into a variable that is defined as an integer value since the property on the user object has to be an integer value.

[int]$primarygroupid = $groupsid.Value.Substring($groupsid.Value.LastIndexOf("-")+1)

Finally we can update the user object with the primary group ID value

Set-ADUser "user" -Replace @{primaryGroupID=$primarygroupid}
Comments Off on Interlude III : Setting Primary Group ID Posted in Uncategorized

Spam sucks

Today I found an email from Diane Schultz ( diane@franchise-path.com ) which was quite obviously a form email trying to get me to buy into a franchising scheme. The really odd post was it was on an email address I exclusively use for job searches. And it was done using a spamming outfit called Stream Send ( http://www.streamsend.com ).  Stream Send lists among its partners and affiliates the DMA, which means that they probably follow the same harvest-spam-make-them-opt-out misbehavior of other DMA partners.

To both of them – thank you for wasting my time with junk there was no reason to think I would be interested in.

Unlocking an account on every DC without forcing replication

Today I’m going to go over a script which will address an issue admins in a large network face : unlocking an account on DCs that spread across multiple WAN links WITHOUT FORCING A REPLICATION.

This script is fairly straight forward but does require the person running it have domain admin privileges and access to the AD PowerShell extensions.

The core of what is needed is a simple command : Unlock-ADAccount. We can start by laying out that command:

Unlock-ADAccount <user>

Since we are interested in doing this on all DCs we’ll include the option -Server. Obviously we can do it the hard way:

Unlock-ADAccount <user> -Server DC1
Unlock-ADAccount <user> -Server DC2
….

But that is hard work if you have a lot of DCs, say 50 or more, or if the DCs are changing. So let’s add something to the script to make it smarter:

$DCList = Get-ADComputer -Filter * -SearchBase ‘ou=Domain Controllers,dc=contoso,dc=com’
Foreach ($targetDC in $DCList.Name)
{
Unlock-ADAccount <user> -Server $targetDC
}

We’ve added a little brains here. The Get-ADComputer cmdlet is used to get the names of all the computers [-Filter *] in our Domain Controllers OU [-SearchBase ‘ou=Domain Controllers,dc=contoso,dc=com’]. We’re dumping the results of this command into the variable $DCList. The end result is that we wind up with an array where each item in the array has multiple properties. We’re interested in one, Name. The Foreach command essentially allows us to loop through all of the array values one at a time. We use another single-value variable, $targetDC, to hold the current DC name. In five lines we are able to do what might take a hundred or more.

So far so good. But what happens if a DC is offline or unreachable? The script blows up. We’ll add an option to our Unlock-ADAccount cmdlet to keep everything going along rather than just halting

$DCList = Get-ADComputer -Filter * -SearchBase ‘ou=Domain Controllers,dc=contoso,dc=com’
Foreach ($targetDC in $DCList.Name)
{
Unlock-ADAccount <user> -Server $targetDC -ErrorAction SilentlyContinue
}

Now the script will just roll on if it hits a downed DC. But it would be nice to know about that, right? So let’s add TRY-CATCH

$DCList = Get-ADComputer -Filter * -SearchBase ‘ou=Domain Controllers,dc=contoso,dc=com’
Foreach ($targetDC in $DCList.Name)
{
Try
{
Unlock-ADAccount <user> -Server $targetDC -ErrorAction SilentlyContinue
}
Catch
{
$errormsg = $targetDC + ” is down/not responding.”
Write-Host $errormsg -ForegroundColor white -BackgroundColor red
}
}

There. Now we get a message indicating a particular DC was down. The ForegroundColor option allows us to specify white as the text color, while the BackgroundColor option allows us to specify red as the text background, making it stand out in our shell window.

But if we’re doing that why not give ourselves a clue as to where we’re at by doing something similar in the Try section:

$DCList = Get-ADComputer -Filter * -SearchBase ‘ou=Domain Controllers,dc=contoso,dc=com’
Foreach ($targetDC in $DCList.Name)
{
Try
{
Unlock-ADAccount <user> -Server $targetDC -ErrorAction SilentlyContinue
Write-Host (“Completed on ” + $targetDC) -BackgroundColor DarkGreen
}
Catch
{
$errormsg = $targetDC + ” is down/not responding.”
Write-Host $errormsg -ForegroundColor white -BackgroundColor red
}
}

Great, but it’s kind of useless to have to adjust the script for each user. Let’s add an argument to our script and, before trying the script, check to make sure it isn’t empty.

$targetacct = $args[0]
if ($targetacct -ne $null)
{
$DClist = get-adcomputer -filter * -SearchBase ‘ou=domain controllers,dc=contoso,dc=com’ | Sort-Object name
Try
{
Get-ADUser $targetacct
Foreach ($targetDC in $DClist.Name)
{
“Processing ” + $targetacct + ” on DC ” + $targetDC | Out-Default
Try
{
Unlock-ADAccount $targetacct -Server $targetDC -ErrorAction SilentlyContinue | Out-Null
Write-Host (“Completed on ” + $targetDC) -BackgroundColor DarkGreen
}
Catch
{
$errormsg = $targetDC + ” is down/not responding.”
Write-Host $errormsg -ForegroundColor white -BackgroundColor Red
}
}
}
Catch
{
$errormsg = $targetacct + ” is an INVALID account. Check to see if it exists and that this is the SAM name.”
Write-Host $errormsg -ForegroundColor white -BackgroundColor Red
}
}
else
{
write-host “INVALID Parameters!”
Write-Host “USAGE: unlock.ps1 <USERNAME>”
}

Not only have we added the input from arguments (the first line), but in the second line we set up an IF-ELSE structure to ensure we have an actual value. [And yell at us when we don’t!] We also added an additional line [“Processing….”] so that we have an even better idea of what is being tried, not just whether it succeeded or not. There’s even a check [Try … Get-ADUser….] to see if the account actually exists and exit if it doesn’t.

Granted this is a linear script and can several minutes to run based on WAN links and DC load, but that is a lot better that forcing a replication across multiple small pipes.

Comments Off on Unlocking an account on every DC without forcing replication Posted in Uncategorized