PowerShell Get-ClusterGroup won't allow multiple nodes - powershell-2.0

I am trying to come up with a script to verify that cluster resources are online on multiple clusters based on a list. I have the below but Get-Content is not working. I've tried quotes and parenthesis around "Get-Content" but still nothing. If I put just the node names separated by comma's, it works fine. What am I missing? Also, how can I filter out the "Cluster Group" and Available Storage" in the results? I really only want to know if the resources are online. Thank you.
Import-Module FailoverClusters
$clusters = Get-Content -Path C:\clusters.txt
ForEach ($cluster in $clusters)
{
$clusterNodes = Get-ClusterGroup -Cluster $cluster ;
$clusterNodes|select Name,OwnerNode, State|Sort-Object NodeName|Format-Table -Wrap -AutoSize;
}
------------Results--------------
Name OwnerNode State
---- --------- -----
Resource1 Server1 Online
Cluster Group Server2 Online
Available Storage Server2 Online
Resource2 Server1 Online
Resource3 Server1 Online
Resource4 Server1 Online

Filter it out based on the cluster resources property iscoregroup
get-clustergroup | where iscoregroup -eq $false | select name, ownernode, state |Sort-Object
NodeName|Format-Table -Wrap -AutoSize;

Related

How to change Get-Mailbox output

I apologize in advance as I am still fairly new to powershell. I'm figuring things out as I go, but this specific issue is stumping me. Currently this is with powershell 2.0 on exchange 2007.
I am trying to add to a script that I have been writing up that shows the basic information for our exchange accounts. This is just a small tool to be introduced to our help desk to assist in a quick overview of what is going on with a user's account. I have everything working, however, I want to change what is displayed. For example, I have:
Get-Mailbox $username | ft #{label="Hidden from GAL"; expression= {$_.HiddenFromAddressListsEnabled}}, #{label="Restricted Delivery"; expression={$_.AcceptMessagesOnlyFrom}} -auto | out-string;
Which ends up returning true/false for hidden from address list, but for Accept Messages, if it is disabled, it returns "{}" (without quotes). If it is enabled, it displays the full group name (along the lines of admin.local/groupname). I only want to change {} to disabled, and instead of showing the group name, just show "enabled"
I tried an if/then statement, and then tried putting the variable "messRestrict" in the expression for accept messages above, and then the function name, but neither worked. They just returned blank values or always said "true." Here is the function:
function restricted {
$accept = Get-Mailbox $username | AcceptMessagesOnlyFrom | select -expand Priority
#if ($accept -match "\s")
#{$messRestrict="False"};
#else
#{$messRestrict="True"};
}
The output is the standard Get-Mailbox output, I just want to replace what it says under the header.
Thanks!
You can try this :
#{label="Restricted Delivery"; expression={if($_.AcceptMessagesOnlyFrom){"Enabled"}else{"Disabled"}}}
It gives :
Get-Mailbox $username | ft #{label="Hidden from GAL"; expression= {$_.HiddenFromAddressListsEnabled}}, #{label="Restricted Delivery"; expression={if($_.AcceptMessagesOnlyFrom){"Enabled"}else{"Disabled"}}} -auto | out-string;

how to increase efficiency of invoke-command using session to collect logs from remote computer in powershell?

how to increase efficiency of invoke-command using session to collect logs from remote computer in powershell?Its taking 1min 51sec for collecting 98k no. of logs for me.
i measured the performance using the following code :
Measure-Command
{
invoke-command -Credential $cred -cn $user -ScriptBlock
{
get-wmiobject -class win32_ntlogevent;
}
}
(I can't comment yet as I don't have enough reputation)
Would some of the other Event Log based cmdlets be useful here?
For example:
Get-EventLog (if using v2 or newer)
Get-Event (if using v1)
Get-WinEvent
Take a look at the output of Get-Command *event* for more options depending on what exactly you need to collect and what you need to do with it.
You could use the Measure-Command to see which returns the data faster.

Parse through text file and write out data

I'm working on the first steps towards creating a powershell script that will read through printer logs (probably using get-WMI cmdlet), and parse through the logs. Afterwards, I plan on having the script output to a .txt file the name of the printer, a counter of the number of times a printer was used (if possible), and specific info found in the logs.
In order to do this, I've decided to try working backwards. Below is a small portion of what the logs will look like:
10 Document 81, A361058/GPR0000151814_1: owned by A361058 was printed on R3556 via port IP_***.***.***.***. Size in bytes: 53704; pages printed: 2 20130219123105.000000-300
10 Document 80, A361058/GPR0000151802_1: owned by A361058 was printed on R3556 via port IP_***.***.***.***. Size in bytes: 53700; pages printed: 2
Working backwards and just focusing on parsing first, I'd like to be able to specifically get the "/GRP", "R3446 (in general, R** as this is the printer name)", and get a counter that shows how often a specific printer appeared in the log files.
It has been a while since I last worked with Powershell, however at the moment this is what I've managed to create in order to try accomplishing my goal:
Select-String -Path "C:\Documents and Settings\a411882\My Documents\Scripts\Print Parse Test.txt" -Pattern "/GPR", " R****" -AllMatches -SimpleMatch
The code does not produce any errors, however I'm also unable to get any output to appear on screen to see if I'm capturing the /GRP and printer name. At the moment I'm trying to just ensure I'm gathering the right output before worrying about any counters. Would anyone be able to assist me and tell me what I'm doing wrong with my code?
Thanks!
EDIT: Fixed a small error with my code that was causing no data to appear on screen. At the moment this code outputs the entire two lines of test text instead of only outputting the /GPR and server name. The new output is the following:
My Documents\Scripts\Print Parse Test.txt:1:10 Document 81, A361058/GPR0000151814_1: owned by A361058 was printed on
R3556 via port IP_***.***.***.***. Size in bytes: 53704; pages printed: 2
20130219123105.000000-300
My Documents\Scripts\Print Parse Test.txt:2:10 Document 80, A361058/GPR0000151802_1: owned by A361058 was printed on
R3556 via port IP_***.***.***.***. Size in bytes: 53700; pages printed: 2
I'd like to try having it eventually look something like the following:
/GPR, R****, count: ## (although for now I'm less concerned about the counter)
You can try this. It only returns a line when /GPR (and "on" from "printed on") is present.
Get-Content .\test.txt | % {
if ($_ -match '(?:.*)(/GPR)(?:.*)(?<=on\s)(\w+)(?:.*)') {
$_ -replace '(?:.*)(/GPR)(?:.*)(?<=on\s)(\w+)(?:.*)', '$1,$2'
}
}
Output:
/GPR,R3556
/GPR,R3556
I'm sure there are better regex versions. I'm still learning it :-)
EDIT this is easier to read. The regex is still there for extraction, but I filter out lines with /GPR first using select-string instead:
Get-Content .\test.txt | Select-String -SimpleMatch -AllMatches -Pattern "/GPR" | % {
$_.Line -replace '(?:.*)(/GPR)(?:.*)(?<=on\s)(\w+)(?:.*)', '$1,$2'
}
I generally start with an example of the line I'm matching, and build a regex from that, substituting regex metacharacters for the variable parts of the text. This makes makes the regex longer, but much more intuitive to read later.
Assign the regex to a variable, and then use that variable in subsequent code to keep the messy details of the regex from cluttering up the rest of the code:
[regex]$DocPrinted =
'Document \d\d, \w+/(\D{3})[0-9_]+: owned by \w+ was printed on (\w+) via port IP_[0-9.]+ Size in bytes: \d+; pages printed: \d+'
get-content <log file> |
foreach {
if ($_ -match $DocPrinted)
{
$line -match $docprinted > $null
$matches
}
}

using cmd to create .txt containing url based on ipconfig and modem-required info

I'm not too familiar with cmd or anything, but I have done some research and put together a bit of what I want. This .bat I'm trying to make would take the output of ipconfig/all and select the mac address and ip address of the ethernet adapter and insert them in key locations in a pre-prescribed url for those instances when a computer doesn't automatically redirect to the front page of my hotel's internet billing setup. this is not official work; I am only trying to "ease my burden" a bit and save time typing.
the full address I need to create in a .txt is 000.000.000.00/defaulta.php?mac=xxxxxxxxxxxx&ip=xxx.xxx.xx.xxx
everything but the mac and ip address (both listed as x's) are exactly as they need to be in every case. the ip address shown censored with 0's is intentionally changed for security reasons, and no work needs to be done for that. I have been able to create a simple .bat to create an output of the ipconfig data onto any user's desktop for easy access:
#echo off
ipconfig/all > %userprofile%\Desktop\url_address.txt
I have tried using other parsing solutions to get the data that I need, but the one easiest for me to adapt (linked here) would only output the last instance, not the first or any in between when I make the simplest substitution. I could try to use one of the solutions for only selecting certain lines, but I've seen some computers listing their ethernet first and wireless second, while others list wireless first and ethernet second. I need to parse based specifically on the ethernet lines, as wireless internet is not available in the rooms.
here's an example of the output from my personal pc:
Ethernet adapter Local Area Connection:
Connection-specific DNS Suffix . : xxxx.net
Description . . . . . . . . . . . : Atheros AR8121/AR8113/AR8114 PCI-E Ethernet Controller
Physical Address. . . . . . . . . : xx-xx-xx-xx-xx-xx
DHCP Enabled. . . . . . . . . . . : Yes
Autoconfiguration Enabled . . . . : Yes
Link-local IPv6 Address . . . . . : xxxx::xxxx:xxxx:xxxx:xxxx%12(Preferred)
IPv4 Address. . . . . . . . . . . : xxx.xxx.xx.xxx(Preferred)
anyone who looks up their own and compares will see it's not all the same length, so parsing based on length of characters won't work as different guests will have different cards, etc. this means I need to parse two specific points, the physical address for the mac in the url and the ipv4 address for the ip address in the url. would this mean I have to make two texts, one for each parsing? and how will these two variables be able to be inserted into the final url?
so my main questions are:
1) is it possible to take the two parts I need from the ethernet data and insert them into the appropriate places in the required link and put it in a .txt, and if so, what exactly needs to be done?
2) does the full function I intend need to be done through several .txt files being written as the function progresses to the final solution, or can this all be output to one text file on the guest's desktop for less clutter and easier deletion?
Question was tl;dr. Does this do what you're looking for? Modify xxxx.net and 000.000.000.00 as appropriate.
#echo off
setlocal enabledelayedexpansion
set found=0
for /f "tokens=1,2 delims=:(" %%I in ('ipconfig /all') do (
if !found!==1 (
for /f %%x in ('echo "%%I" ^| find "Physical Address"') do set mac=%%J
for /f %%x in ('echo "%%I" ^| findstr "IP[v4]*.Address"') do (
set ip=%%J
goto next
)
)
for /f %%x in ('echo "%%J" ^| find /i "xxxx.net"') do set found=1
)
echo Couldn't scrape info. Press any key to exit.
pause >NUL
goto :EOF
:next
set mac=%mac: =%
start http://000.000.000.00/defaulta.php?mac=%mac:-=%^&ip=%ip: =%
It performs an ipconfig /all and loops through the output, ignoring everything until it encounters xxxx.net (your connection-specific DNS suffix). Then it looks for Physical Address and IPv4 address from there. Spaces have to be removed from both captures, and dashes removed from the MAC address, all through variable string substitution. Then it launches the user's default web browser to visit the URL you built.
If you actually do need this URL written to a text file instead of launched, then change
start http://000.000.000.00/defaulta.php?mac=%mac:-=%^&ip=%ip: =%
to
echo http://000.000.000.00/defaulta.php?mac=%mac:-=%^&ip=%ip: =% >outfile.txt
Be sure to put a space before the > to make sure Windows redirects stdout to the text file rather than whatever number the IP address happens to end with.
UPDATE 2013.02.27:
The above stuff should work regardless of user access level (administrator or normal user). If you want to simulate running as a non-privileged user, run the following command:
runas /trustlevel:0x20000 cmd
... to open a cmd prompt with restricted privileges. Then you can see for yourself that ipconfig /all still works.
For what it's worth, ipconfig /all is not the only place to scrape the IP and MAC address. If you'd like an alternative to the above script, try this one:
#echo off
setlocal
for /f "tokens=1,2 delims=={}," %%I in (
'wmic nicconfig where ^(ipenabled^='TRUE' and dnsdomain is not null^) get ipaddress^, macaddress /format:list'
) do (
if %%I==IPAddress set ip=%%~J
if %%I==MACAddress set mac=%%J
)
start "" "http://000.000.000.00/defaulta.php?mac=%mac::=%&ip=%ip%"
As before, don't forget to change the IP address in the URL as appropriate.
Update 2013.03.29:
Well, since nothing else has worked for every client computer (as wmic will not work on WinXP Home), and just to see whether I could more than anything, here's another one to try -- a batch / JScript hybrid script. Save this with a .bat extension and I think it should work on every version of Windows after 98 and ME (Mistake Edition, if I recall correctly).
As before, don't forget to replace 000.000.000.00 in the url.
#if (#a==#b) #end /* <-- ignore this, please
:: batch portion
#echo off
setlocal
for /f "tokens=1,2" %%I in ('cscript /nologo /e:jscript "%~f0"') do (
set mac=%%I
set ip=%%J
)
start "" "http://000.000.000.00/defaulta.php?mac=%mac::=%&ip=%ip%"
goto :EOF
:: JScript portion (leave this weird bit here, please) --> */
var wmi = GetObject("winmgmts:\\\\.\\root\\cimv2");
var adapters = wmi.InstancesOf("Win32_NetworkAdapterConfiguration");
for (var res=new Enumerator(adapters); !res.atEnd(); res.moveNext()) {
var adapter = res.item();
/* -------------------------------------------------------------
Note to supergaijin: If this script fails like all the others,
try removing "|| !adapter.DNSDomain" from the following line so
it reads as follows: if (!adapter.IPEnabled) continue;
------------------------------------------------------------- */
if (!adapter.IPEnabled || !adapter.DNSDomain) continue;
WSH.Echo(adapter.MACAddress + ' ' + adapter.IPAddress.toArray()[0]);
}
Credits: I stumbled upon the Win32_NetworkAdapterConfiguration class using WMI Explorer. I figured out how to query its child instances with the help of Scriptomatic (which was much more useful than the TechNet documentation).

Windows command to get service status?

I need to know the status of a service at the end of my batch script which restarts services using "net stop thingie" and "net start thingie".
In my most favorite ideal world, I would like to e-mail the state to myself, to read on cold winter nights, to reassure myself with the warmth and comfort of a server that I know is running right.
Just for you to know, I'm using a Windows server 2003 platform, and a batch file seemed the best choice. I don't mind using something else, and would be very open to suggestions, but just for the sake of knowledge (as a zombie craves brains, I thought, why not inflate my own), is there a command that allows me to check on the status of a service, in command line?
Should I just redirect the output of the command to a file?
Where the hell are my pants? (Gosh, I really do hope the humor inserted in this will not insult anyone. It's Wednesday morning, and humor I do need too :P)
[Edit:] The solution I used is (no longer) available for download from --link redacted--
It is used as a task set to be executed during the night, and checking my e-mail in the morning, I see whether or not the service has correctly restarted.
Have you tried sc.exe?
C:\> for /f "tokens=2*" %a in ('sc query audiosrv ^| findstr STATE') do echo %b
4 RUNNING
C:\> for /f "tokens=2*" %a in ('sc query sharedaccess ^| findstr STATE') do echo %b
1 STOPPED
Note that inside a batch file you'd double each percent sign.
You can call net start "service name" on your service. If it's not started, it'll start it and return errorlevel=0, if it's already started it'll return errorlevel=2.
Using pstools - in particular psservice and "query" - for example:
psservice query "serviceName"
look also hier:
NET START | FIND "Service name" > nul
IF errorlevel 1 ECHO The service is not running
just copied from:
http://ss64.com/nt/sc.html
If PowerShell is available to you...
Get-Service -DisplayName *Network* | ForEach-Object{Write-Host $_.Status : $_.Name}
Will give you...
Stopped : napagent
Stopped : NetDDE
Stopped : NetDDEdsdm
Running : Netman
Running : Nla
Stopped : WMPNetworkSvc
Stopped : xmlprov
You can replace the ****Network**** with a specific service name if you just need to check one service.
Using Windows Script:
Set ComputerObj = GetObject("WinNT://MYCOMPUTER")
ComputerObj.Filter = Array("Service")
For Each Service in ComputerObj
WScript.Echo "Service display name = " & Service.DisplayName
WScript.Echo "Service account name = " & Service.ServiceAccountName
WScript.Echo "Service executable = " & Service.Path
WScript.Echo "Current status = " & Service.Status
Next
You can easily filter the above for the specific service you want.
Well i see "Nick Kavadias" telling this:
"according to this http://www.computerhope.com/nethlp.htm it should be NET START /LIST ..."
If you type in Windows XP this:
NET START /LIST
you will get an error, just type instead
NET START
The /LIST is only for Windows 2000... If you fully read such web you would see the /LIST is only on Windows 2000 section.
Hope this helps!!!
my intention was to create a script which switches services ON and OFF (in 1 script)
net start NameOfSercive 2>nul
if errorlevel 2 goto AlreadyRunning
if errorlevel 1 goto Error
...
Helped a lot!! TYVM z666
but when e.g. service is disabled(also errorlevel =2?)it goes to "AlreadyRuning"and never comes to
if errorlevel 1 goto Error ?!!
i wanted an output for that case ...
:AlreadyRunning
net stop NameOfSercive
if errorlevel 1 goto Error
:Error
Echo ERROR!!1!
Pause
my 2 Cents, hope this helps
Maybe this could be the best way to start a service and check the result
Of course from inside a Batch like File.BAT put something like this example but just replace "NameOfSercive" with the service name you want and replace the REM lines with your own code:
#ECHO OFF
REM Put whatever your Batch may do before trying to start the service
net start NameOfSercive 2>nul
if errorlevel 2 goto AlreadyRunning
if errorlevel 1 goto Error
REM Put Whatever you want in case Service was not running and start correctly
GOTO ContinueWithBatch
:AlreadyRunning
REM Put Whatever you want in case Service was already running
GOTO ContinueWithBatch
:Error
REM Put Whatever you want in case Service fail to start
GOTO ContinueWithBatch
:ContinueWithBatch
REM Put whatever else your Batch may do
Another thing is to check for its state without changing it, for that there is a much more simple way to do it, just run:
net start
As that, without parameters it will show a list with all services that are started...
So a simple grep or find after it on a pipe would fit...
Of course from inside a Batch like File.BAT put something like this example but just replace "NameOfSercive" with the service name you want and replace the REM lines with your own code:
#ECHO OFF
REM Put here any code to be run before check for Service
SET TemporalFile=TemporalFile.TXT
NET START | FIND /N "NameOfSercive" > %TemporalFile%
SET CountLines=0
FOR /F %%X IN (%TemporalFile%) DO SET /A CountLines=1+CountLines
IF 0==%CountLines% GOTO ServiceIsNotRunning
REM Put here any code to be run if Service Is Running
GOTO ContinueWithBatch
:ServiceIsNotRunning
REM Put here any code to be run if Service Is Not Running
GOTO ContinueWithBatch
:ContinueWithBatch
DEL -P %TemporalFile% 2>nul
SET TemporalFile=
REM Put here any code to be run after check for Service
Hope this can help!! It is what i normally use.
Well I'm not sure about whether you can email the results of that from a batch file. If I may make an alternate suggestion that would solve your problem vbscript. I am far from great with vbscript but you can use it to query the services running on the local machine. The script below will email you the status of all of the services running on the machine the script gets run on. You'll obviously want to replace the smtp server and the email address. If you're part of a domain and you run this script as a privileged user (they have to be an administrator on the remote machine) you can query remote machines as well by replacing localhost with the fqdn.
Dim objComputer, objMessage
Dim strEmail
' If there is an error getting the status of a service it will attempt to move on to the next one
On Error Resume Next
' Email Setup
Set objMessage = CreateObject("CDO.Message")
objMessage.Subject = "Service Status Report"
objMessage.From = "service_report#noreply.net"
objMessage.To = "youraddress#example.net"
objMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
'Name or IP of Remote SMTP Server
objMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "smtp.example.net"
'Server port (typically 25)
objMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
Set objComputer = GetObject("WinNT://localhost")
objComputer.Filter = Array("Service")
For Each aService In objComputer
strEmail = strEmail &chr(10) & aService.Name & "=" & aService.Status
Next
objMessage.TextBody = strEmail
objMessage.Configuration.Fields.Update
objMessage.Send
Hope this helps you! Enjoy!
Edit: Ahh one more thing a service status of 4 means the service is running, a service status of 1 means it's not. I'm not sure what 2 or 3 means but I'm willing to bet they are stopping/starting.
according to this http://www.computerhope.com/nethlp.htm it should be NET START /LIST but i can't get it to work on by XP box. I'm sure there's some WMI that will give you the list.
Ros the code i post also is for knowing how many services are running...
Imagine you want to know how many services are like Oracle* then you put Oracle instead of NameOfSercive... and you get the number of services like Oracle* running on the variable %CountLines% and if you want to do something if there are only 4 you can do something like this:
IF 4==%CountLines% GOTO FourServicesAreRunning
That is much more powerfull... and your code does not let you to know if desired service is running ... if there is another srecive starting with same name... imagine:
-ServiceOne
-ServiceOnePersonal
If you search for ServiceOne, but it is only running ServiceOnePersonal your code will tell ServiceOne is running...
My code can be easly changed, since it reads all lines of the file and read line by line it can also do whatever you want to each service... see this:
#ECHO OFF
REM Put here any code to be run before check for Services
SET TemporalFile=TemporalFile.TXT
NET START > %TemporalFile%
SET CountLines=0
FOR /F "delims=" %%X IN (%TemporalFile%) DO SET /A CountLines=1+CountLines
SETLOCAL EnableDelayedExpansion
SET CountLine=0
FOR /F "delims=" %%X IN (%TemporalFile%) DO #(
SET /A CountLine=1+CountLine
REM Do whatever you want to each line here, remember first and last are special not service names
IF 1==!CountLine! (
REM Do whatever you want with special first line, not a service.
) ELSE IF %CountLines%==!CountLine! (
REM Do whatever you want with special last line, not a service.
) ELSE (
REM Do whatever you want with rest lines, for each service.
REM For example echo its position number and name:
echo !CountLine! - %%X
REM Or filter by exact name (do not forget to not remove the three spaces at begining):
IF " NameOfService"=="%%X" (
REM Do whatever you want with Service filtered.
)
)
REM Do whatever more you want to all lines here, remember two first are special as last one
)
DEL -P %TemporalFile% 2>nul
SET TemporalFile=
REM Put here any code to be run after check for Services
Of course it only list running services, i do not know any way net can list not running services...
Hope this helps!!!

Resources