cant return right value from powershell script - powershell

Help me pls,
i'am going my mind, what is wrong in my script??? i'm testing this script under Windows 2012.
There is shares:
\FS-SHARES\TEST12
\FS-SHARES\TEST15
\FS-SHARES\TEST20
function StripShare($sharename) {
$res=$sharename -replace ".*\\(.*)" , '$1'
return $res
}
function getShareProp($sharename) {
$s=""
Get-WmiObject -class Win32_Share -computername "." -filter "Type=0" | % {
if (stripshare($_.name) -eq $sharename) {
$s=$_.name
}
}
return $s
}
getShareProp(stripshare("s:\TEST12"))
OUTPUT
----
TEST20
getShareProp(stripshare("s:\TEST15"))
---
OUTPUT
TEST20
Solved!
p.s. Something strange with pipeline in powershell 3.
function getShareProp($sharename) {
$s=""
$a=Get-WmiObject -class Win32_Share -computername "." -filter "Type=0"
foreach ($_ in $a) {
$t=stripshare($_.name)
if ($t -eq $sharename) {
$s=$_.name
}
}
return $s
}

I'm not sure I understand what you are attempting to accomplish, but I think just adding to the filter will mostly provide the same functionality.
Get-WmiObject -class Win32_Share -computername "." -filter "Type=0 and name='TEST12'" | select Name
or if you're looking for the Share name associated with a physical path.
Get-WmiObject -class Win32_Share -computername "." -filter "Type=0 and path='S:\TEST12'" | select Name

Related

Getting single, specific drive status using powershell?

Running this:
$WMI = Get-WMIObject -Class Win32_DiskDrive
ForEach ($Drive in $WMI){
$Drive.DeviceID + ": " + $Drive.Status
}
Returns results like:
\\.\PHYSICALDRIVE1: OK
\\.\PHYSICALDRIVE0: OK
\\.\PHYSICALDRIVE2: OK
\\.\PHYSICALDRIVE3: OK
Is there an easy way to restrict results to \.\PHYSICALDRIVE0?
Basically, I am trying to return a simple "OK" for Physical Drive 0's health.
I tried the following:
$WMI = Get-WMIObject -Class Win32_DiskDrive
ForEach ($Drive in $WMI | Where $Drive.DeviceID -Contains "\\.\PHYSICALDRIVE0"){
$Drive.Status
}
But nothing is outputted (at all). How would I restrict the status output to just the Physical Drive 0 from DeviceID?
I would do it this way:
$WMI = Get-WMIObject -Class Win32_DiskDrive
ForEach ($Drive in $WMI) {
if ($Drive.DeviceID -contains "\\.\PHYSICALDRIVE0") {
$Drive.Status
}
}
You look thru $wmi and check if each value contains this specific value.
If you have a match, it will show the Disk status.
There are many ways, depending on how specific you wish to be:
Get-WMIObject -Class Win32_DiskDrive | Where-Object DeviceID -eq '\\.\PHYSICALDRIVE0'
Get-WMIObject -Class Win32_DiskDrive | Where-Object DeviceID -match 'E0$'
Get-WMIObject -Class Win32_DiskDrive | Where-Object Index -eq 0
If you wish these to run on older versions of PowerShell, then use the older syntax by placing each "test" into a scriptblock:
Get-WMIObject -Class Win32_DiskDrive | Where-Object { $_.DeviceID -eq '\\.\PHYSICALDRIVE0' }

Trying to return info on computer names for test

$computers = Get-Content C:\computers.txt #| Where-Object { $_ }
foreach ($computer in $computers) {
(Get-CIMInstance CIM_ComputerSystem).Name
}
Why is the above code only returning the local computer name, shouldnt it select the computers in the text file and return their computer names?
You forgot this part. Happens to the best of us.
-ComputerName $Computer
(Get-CIMInstance -ComputerName $Computer CIM_ComputerSystem).Name

Use WMI to convert a remote SID to username

I am using Invoke-WMIMethod to identify all SIDS beginning with S-1-5-21, like so (thanks to Mathias R. Jessen):
$Keys = Invoke-WmiMethod -Path $ClassPath -Name EnumKey -ArgumentList 2147483651,''
| Select-Object -ExpandProperty sNames | Where-Object {$_ -match 'S-1-5-21-[\d\-]+$'}
I want to convert these SIDs from the remote system to usernames on the remote system using WMI. Is this possible through WMI or Invoke-WmiMethod?
You can use the Win32_SID class to obtain the account name:
foreach($Key in $Keys)
{
$SID = [wmi]"\\$RemoteComputer\root\cimv2:Win32_SID.SID=$Key"
New-Object psobject -Property #{
SID = $Key
Username = $SID.ReferencedDomainName,$SID.AccountName -join '\'
}
}
Rather than grabbing from the registry you could get the same information from the Win32_UserProfile provider. Then if folder name is good enough, consider something like this:
$Computer = "ExampleComputer"
Get-WMIObject Win32_UserProfile -Filter "SID like 'S-1-5-21-*'" -ComputerName $Computer |
select SID,#{name=LocalPath;Expression={Split-Path -leaf $_.LocalPath}}
Otherwise Win32_UserAccount exists but can be really slow with a large domain.
$Computer = "ExampleComputer"
$SIDs = Get-WMIObject Win32_UserProfile -Filter "SID like 'S-1-5-21-*'" -ComputerName $Computer | select -ExpandProperty SID
$UserAccounts = Get-WMIObject Win32_UserAccount -ComputerName $Computer
foreach ($SID in $SIDs) {
foreach ($Account in $UserAccounts) {
If ($SID -eq $Account.SID) {
$Account
}
}
}

CASE, IFElse, or SWITCH Powershell to change output of Get-WmiObject

I have the following code that works as a stand-alone query:
$Type = (Invoke-Command -ComputerName $Computer -ScriptBlock { Get-WmiObject -Class Win32_ComputerSystem | Select-Object -ExpandProperty Manufacturer })
switch -regex ($Type)
{
"VMw.+" {"VM"}
default {"Physical"}
}
I want to add the switch command within the Invoke command instead of a variable (dropping the $Type variable) so that it can be run against multiple computers, how can this be accomplished, I am not determined to use Switch to accomplish the end result?
Get-WmiObject has a ComputerName property so you don't need to use Invoke-Command
switch -regex (Get-WmiObject -ComputerName $Computer -Class Win32_ComputerSystem | Select-Object -ExpandProperty Manufacturer)
{
"VMw.+" {"VM"}
default {"Physical"}
}
And by wrapping it in a simple foreach loop you can easily run it against multiple computers:
$Computers = "computer1","computer3","computer3"
foreach ($Computer in $Computers) {
switch -regex (Get-WmiObject -ComputerName $Computer -Class Win32_ComputerSystem | Select-Object -ExpandProperty Manufacturer)
{
"VMw.+" {Write-Output "$Computer is a VM Computer"}
default {Write-Output "$Computer is a Physical Computer"}
}
}

Powershell: Pipe variable $_ in if statement?

I have the following short script to grab serial numbers of computers and monitors in an OU, which works fine:
Import-Module ActiveDirectory
$searchbase = "OU=some,OU=organisational,OU=units,DC=somedomain,DC=local"
Write-Host ""
Write-Host "Serial Numbers for Computers and Monitors in" $searchbase
Write-Host "--"
Get-ADComputer -SearchBase $searchbase -Filter '*' | `
Select-Object -Expand Name | %{Write-Host ""; echo $_ ; Get-WMIObject -Class Win32_BIOS -ComputerName $_ | Select-Object -Expand SerialNumber; `
$monitor = gwmi WmiMonitorID -Namespace root\wmi -computername $_; ($monitor.SerialNumberID | foreach {[char]$_}) -join ""};
This script doesn't check to see if the computer is online before attempting to fetch the WMIObject, so if a computer is offline it takes ages before the RPC call times out.
I tried to modify the script to use the Test-Connection cmdlet before trying to get the WMIObject:
Import-Module ActiveDirectory
$searchbase = "OU=some,OU=organisational,OU=units,DC=somedomain,DC=local"
Write-Host ""
Write-Host "Serial Numbers for Computers and Monitors in" $searchbase
Write-Host "--"
Get-ADComputer -SearchBase $searchbase -Filter '*' | `
Select-Object -Expand Name | `
if (Test-Connection -ComputerName $_ -Quiet) {
%{Write-Host ""; echo $_ ; Get-WMIObject -Class Win32_BIOS -ComputerName $_ | Select-Object -Expand SerialNumber; `
$monitor = gwmi WmiMonitorID -Namespace root\wmi -computername $_; ($monitor.SerialNumberID | foreach {[char]$_}) -join ""};}
}
else {
Write-Host ""; Write-Host $_ "is offline";
}
I'm sure I'm doing something syntactically stupid. Can someone point me in the right direction?
You can't pipe directly to an if statement, only to cmdlets.
Put the if statement inside the ForEach-Object block (% is an alias for ForEach-Object):
... | Select-Object -Expand Name | `
%{
if (Test-Connection -ComputerName $_ -Quiet) {
# Get-WmiObject in here
}
else {
Write-Host ""; Write-Host $_ "is offline";
}
}
If you don't care about writing each machine's status to the host, you could also filter out offline computers with Where-Object(alias ?):
... | Select-Object -Expand Name | ?{
Test-Connection $_ -Quiet
} | % {
Get-WmiObject -ComputerName $_
}
In addition to the answer from #Mathias R. Jessen, you can get rid of the backticks for line continuation.
They are not needed if the end of the line infers there is another block of code required for the statement. Like | or { or (.
"foo", "bar" |
% {$_}
works just fine...