1

Our organisation renames all new computers before they join our domain and I am trying to create a script to display the next available number.

So, our naming convention is as follows

Example:

GBYOR-DT1

   GB      -   YOR     -   DT     -     1
[Country]     [City]    [Desktop]    [Number]

However my predecessor thought to number these in no logical order and that just isn't happening on my watch. (Did someone say OCD?)

Currently I run

> Get-ADComputer -Filter * | where{$_.Name -Like "GBYOR-DT*" | FL Name | Export-CSV -Path "X Location"

I then go into Excel, split the cells and the sort numerically.

What I would like is to create a script that just shows me the next available number.

For example, as it currently stands, we have X number of machines, one is GBYOR-DT4, another is GBYOR-DT245 but there is no GBYOR-DT15.

I would like to script this so that when I run it, it will look at all of the machines registered on our domain and then display the next one

> GBYOR-DT1 
> GBYOR-DT2 
> GBYOR-DT3 
> GBYOR-DT4 
> GBYOR-DT6

> 
> ...GBYOR-DT5 does not exist so this is the next number to use for renaming.

Any help would be appreciated.

  • Should the number continue for each prefix or globally? – vrdse Jul 26 '18 at 16:21
  • 1
    There is no need to switch to excel, to sort numbers with different length use [$ToNatural](https://stackoverflow.com/a/5429048/6811411) and iterate the result to check where is a gap to the predecessor. –  Jul 26 '18 at 16:33
  • @PetSerAl - if you have the time, would you please post your comment as an answer with explanation? Will upvote if you choose to post answer. Your solution is **very** nice, and IMHO this technique is what scripting languages in general are great for. :) – kuujinbo Jul 26 '18 at 17:02
  • 2
    Possible duplicate of [Find free number in a range](https://stackoverflow.com/questions/15358126/find-free-number-in-a-range) – TessellatingHeckler Jul 26 '18 at 17:59

2 Answers2

1
$ComputerNames = 'GBYOR-DT1', 'GBYOR-DT4', 'GBYOR-DT6', 
                 'GBYOR-DT10', 'GBYOR-DT2', 'GBYOR-DT3'

Compare-Object (1..15) ($ComputerNames -replace '.*?(?=\d+$)' -as [int[]]) -PassThru

Where 15 is some number higher than the max, assuming you know or can guess such.

And the regex replaces all the text before any numbers, in each computer name.

Solution taken from: Find free number in a range

TessellatingHeckler
  • 27,511
  • 4
  • 48
  • 87
0

To have it more universal I put together this script,
It's a bit different from PetSerAls comment and also from my suggestion.

For testing I feed names in and two real commands are commented out.

## Q:\Test\2018\07\26\SO_51543166.ps1

$Prefix = Read-Host -Prompt "Enter the computer name prefix to search the first free number for"
$Prefix -match '^(.*?)\d*$' | Out-Null # strip possibly trailing numbers
$Prefix = $Matches[1]

$Number = 0 # initialize last Number to zero
'GBYOR-DT1', 'GBYOR-DT4', 'GBYOR-DT6', 'GBYOR-DT10', 'GBYOR-DT2', 'GBYOR-DT3'|
Where-Object {$_ -match "^$Prefix(\d+)$" }|
#Get-ADComputer -Filter * |
#Where-Object {$_.Name -match "^$Prefix(\d+)$" }|
   Select-Object @{n='UsedNumber';e={[int]$Matches[1]}} | Sort-Object UsedNumber |
      ForEach-Object {
         While ($Number +1 -lt $_.UsedNumber){"Free: {0}{1}" -f $Prefix,++$Number}
         $Number = $_.UsedNumber
      }
# if there was no gap get the next one.
"Free: {0}{1}" -f $Prefix,++$Number

Sample run:

> Q:\Test\2018\07\26\SO_51543166.ps1
Enter the computer name prefix to search the first free number for: GBYOR-DT
Free: GBYOR-DT5
Free: GBYOR-DT7
Free: GBYOR-DT8
Free: GBYOR-DT9
Free: GBYOR-DT11

To have a life test remove or comment these two lines:

'GBYOR-DT1', 'GBYOR-DT4', 'GBYOR-DT6', 'GBYOR-DT10', 'GBYOR-DT2', 'GBYOR-DT3'|
Where-Object {$_ -match "^$Prefix(\d+)$" }|

and uncomment these:

Get-ADComputer -Filter * |
Where-Object {$_.Name -match "^$Prefix(\d+)$" }