Hi! This is my first time posting here so hopefully I’m not committing any faux pas.
I’m trying to pull a computer name from AD based on a partial name. All of our computers are named ending with an asset tag number. My script prompts for that number and then attempts to find a computer in AD with a name ending with that number. The script finds the right name, but it’s in a format that I wasn’t expecting, and being a PowerShell novice, I’m not sure how to fix. Here’s the code:
$AssetNo = Read-Host "Enter the asset number"
$TargetPC = Get-ADComputer -Filter "Name -like '*$AssetNo*'" | Select-Object Name
Write-Host
Write-Host "The computer name is: " $TargetPC
Write-Host
Get-WinEvent -ComputerName $TargetPC -FilterHashtable @{
LogName = 'System'
ID = 86
}
The Write-Host commands are just so that I can see what the script is pulling from AD. Assuming the asset number entered is 14489, the value I am getting looks like this:
@{Name=PCName14489}
I need it to just be:
PCName14489
I found the Get-WinEvent block online and it works if I modify the code to prompt the user for the full computer name.
Any help will be greatly appreciated!
–Tom
In powershell you get back an object. If you just output the variable $targetpc, you should see several properties and values. You can see what properties are available on the object with
$TargetPC | Get-Member
If you want to see all properties/values, you can do
$TargetPC | Format-List -Property *
You should find the desired value and can see what property it’s under. You seem to want the Name property So you can access just the property while keeping the object whole with
Write-Host "The computer name is: " $TargetPC.Name
Or you can just extract the value from the beginning with
$TargetPC = Get-ADComputer -Filter "Name -like '*$AssetNo*'" | Select-Object -ExpandProperty Name
Then the rest of your code will work. It can be useful to keep the object whole and just reference the properties you need as needed.
2 Likes
After following the advice from @krzydoug your next question might be “why didn’t this produce any output?”.
Checking for error conditions is always a good thing. Try this:
$AssetNo = Read-Host "Enter the asset number"
$TargetPC = Get-ADComputer -Filter "Name -like '\*$AssetNo\*'" | Select-Object Name
if (-NOT $TargetPC){
Write-Host "No computer found for asset number: '$AssetNo'"
}
else{
Write-Host
Write-Host "The computer name is: " $TargetPC
Write-Host
Get-WinEvent -ComputerName $TargetPC -FilterHashtable @{
LogName = 'System'
ID = 86
}
}
1 Like
Perfect! Thanks for the response! This is exactly what I was looking for. I thought there had to be a way to see all the properties available on the object. In fact, that was going to be another question, but you already answered it, so thank you!
–Tom
I was thinking the same thing, so this morning I decided to see what Copilot could do. Never used Copilot before, but it wrote a script with error checking and comments included. Not sure if it’s the tightest, most efficient script, but it worked with no changes needed.
Still planning to pursue some PowerShell training though because I just like to know how to do it myself.
If you’re curious, below is what Copilot came up with (I added the additional requirement of making the event ID a variable). I’d be interested in getting some opinions on whether this is a good script, or garbage. Seems pretty good to me, but I’m a novice, so anything that works seems pretty good to me. LOL! I do kind of prefer you if (-NOT $TargetPC) syntax as that just makes immediate sense to me, whereas the Copilot script I have to study a little bit.
# Prompt the user for the Event ID
$eventID = Read-Host "Enter the Event ID to search for"
# Prompt the user for the remote computer name
$computerName = Read-Host "Enter the remote computer name"
# Query the System log on the remote machine
try {
Write-Host "Querying $computerName for Event ID $eventID..." -ForegroundColor Cyan
$results = Get-WinEvent -FilterHashtable @{
LogName = 'System'
Id = $eventID
} -ComputerName $computerName -ErrorAction Stop
if ($results) {
Write-Host "Events found:" -ForegroundColor Green
$results | Format-Table TimeCreated, Id, LevelDisplayName, Message -AutoSize
}
else {
Write-Host "No events found with ID $eventID on $computerName" -ForegroundColor Yellow
}
}
catch {
Write-Host "Error querying the remote machine: $($_.Exception.Message)" -ForegroundColor Red
}
That CoPilot script doesn’t use the asset number to find the computer object in the AD. That’s different to your original requirements. Neither does it validate that the computer name exists in the AD (also part of your original requirements) before using it in the Get-WinEvent cmdlet.
The reason I didn’t use Try/Catch is because the Get-ADComputer (in your original script) won’t generate an exception if it doesn’t find a match in the AD. That’s a consequence of using the -Filter parameter which just returns a null value if the search yields no results.
What CoPilot did do was to use the -ERRORACTION STOP. That turns any exception into a fatal exception which is needed to trigger the try/catch. That’s something many people forget.
1 Like
Yeah, I caught the issue with finding the name in AD after I posted my last message. Copilot seems like it might be useful in helping to learn PowerShell, but not as a primary source. I would tend toward online classes and a good book. The Copilot script did introduce me to some new cmdlets that I can look up, so that’s helpful, and it had some good suggestions for script enhancement, like looping through a collection of machines. I have been thinking about this script as an as-needed kind of thing, but since event ID 86 is a shutdown due to overheating, running the script on a collection of machines might be a good pre-emptive thing to do.
But those things are down the line once I’ve learned more about PowerShell. For now, the information that kzrydoug and you have provided has resolved my issue. Many thanks!
CoPilot can be a useful tool, but it’s far from perfect. It’ll tell you with a perfectly straight face to use a cmdlet parameter that doesn’t exist. It’ll show you code that works but is very inefficient . . . or simply doesn’t work at all. On the other hand, it can give you answers to problems using techniques that you’d never think of yourself – and sometimes work quite well. Just don’t fall into thinking that “vibe coding” is the way to arrive at a solution every time!
I started using PowerShell before it was called PowerShell. Early on it was named “Monad”.
Three of the books that I found useful were “Windows Powershell TFM (4th edition)”, “Powershell in Depth” and “Powershell in Action (3rd edition)”.
You might still find a copy of “Windows Powershell TFM” somewhere on the net. It used to be available on the Sapien.com web site as a free download, but they discontinued that a few years ago. The 1st half of the book covered the Powershell language, the 2nd half covered using the language with examples of simplified real-world to accomplish administrative tasks.
The “in depth” book covers only up to Powershell 4.0, but that encompasses most of what you’d need.
The “in action” book takes you deeper into the workings of Powershell and covers Powershell 5.
If you’re looking for a free, self-paced, way of learning how to use Powershell, have a look at http://www.exercism.com and the Powershell track. It doesn’t cover any Active Directory topics and some of the later exercises deal more with techniques you’re unlikely to use unless you’re enrolled in a computer science course (feel free to skip those – I did). One of the things you’ll also pick up by working through those examples is an understanding of “Pester”, a tool for writing tests for your code. As your scripts become more complex you’ll want to make sure they pass tests of what you expect them to do given combinations of input data.
Also, use a good editor. VS Code is a good choice. Visual Studio is also a good choice, but it’s probably overkill for what you’ll be doing.
Good luck!
2 Likes
Thanks! A lot of good info there!
I was wondering about AI hallucinations myself. That’s why I wasn’t fully trusting that code. As I recall, the first time I ran that script it worked, but it as you pointed out, it was not pulling the name from AD based on the asset tag number (I must has put in the full name).
I think that I actually have the Windows PowerShell TFM somewhere. I’ll try to hunt that up this weekend. I also have some stuff from Sapien.com. We had them in several years back and got some good training material. I also have Learn PowerShell in a Month of Lunches book that I’ve not dug into yet, although just browsing through the book my first impression is that it’s really more like 3 or 4 months of lunches by the time you really study and understand it all.
I’ll definitely take a look at exercism.com. Never heard of it, but free and self-paced are good. Thanks for the link!
It seems like a lot of people hate the ISE. I do tend to use that, but I also have Visual Studio Code installed, so I have options for my editor.
Thanks for the help and all the great info!
If you intend to use PowerShell (not Windows PowerShell) beyond version 5 the old ISE won’t work. You might as well switch editors now. Just sayin’.