"In words" section of a Windows Event - command-line

Is there any way to view the In words section of an event thru Powershell or thru the command prompt.
I have tried
psloglist -m 120 -s -x
Get-EventLog application | ft TimeGenerated,#{label="Data";expression={[char[]][int[]]$_.data -join ""}}
But none give the desired output.

I got a quick and dirty one, which works on my laptop:
Get-EventLog application | % {
$bytes = $_.Data
while ($bytes.Length % 4 -ne 0) {$bytes = $bytes + #(0)}
for ($i = 0; $i -lt $bytes.Length; $i += 4)
{
$curWord = [System.BitConverter]::ToUInt32($bytes, $i).ToString("X8")
Write-Output $curWord
}
Write-Output ""
}

Related

How to mapping a folder name using PowerShell?

I want to mapping an a folder to download and extract the folder.
This is the way I need to download the folder.
DownloadF.exe --net 10.0.0.1 --user XX --id 00 --ver A00X-F1A >> result.txt
I have 26 version to mapping, which are
A00X-F1A ... A00X-F1Z (the last character is A - Z)
If the result.txt contain of this string "folder available". It means the version is correct, then stop the looping or checking other version.
I must check the version start from A00X-F1Z, A00X-F1Y, A00X-F1X, ... A00X-F1A.
Anyone can give me idea please.
##Updated
$Version = "A00X-F1"
$List_Ver = 90..65 | ForEach-Object{"$Version" + [char]$_}
$n = 0
foreach ($list in $List_Ver){
while ($Result -notcontains "Folder Available")
{
$n++
& DownloadF.exe --net 10.0.0.1 --user XX --id 00 --ver $list >> $list.txt"
Start-Sleep -s 3
$Result = Get-Content -path .\$list.txt
}
}
This is what I tested with what I gather you are looking for,
Sample result.txt
A00X-F1Z
A00X-F1Y
A00X-F1X
A00X-F1W
A00X-F1V
A00X-F1U
A00X-F1T
A00X-F1S
A00X-F1R
A00X-F1Q
Code to work with
$Version = "A00X-F1"
$List_Ver = 90..65 | ForEach-Object{"$Version" + [char]$_}
$result = Get-Content C:\temp\result.txt
$string = "Folder Not Available"
foreach($list in $List_Ver) {
DownloadF.exe --net 10.0.0.1 --user XX --id 00 --ver $list >> result.txt
if ($result -like $string ) {
$n = 0
while ($result -like $string)
{
$n++
Write-Host "Not Found"
Break
}
}
else {
Write-Host "Found"
Break
}
}

Why can't I break my powershell command into multiple lines?

This works (all on one line):
PS C:\> $list.item | % { $t = $_.tags -split ","; if ($t -contains "red") { $_.name } }
This, however, doesn't:
PS C:\> $list.item | % {
>> $t = $_.tags -split ","
>> if ($t -contains "red") { $_.ne }
>> }
>>
No matter what I enter, I just keep getting the ">>" prompt until I hit Ctrl-C.
What's wrong?
To get powershell to execute the command, you would in fact need to press enter twice.

Displaying the output into html

I got a code for pinging the servers repeatedly. That best suits for my object. But the thing I want to display the result of the code to the HTML page. How can I do it?
Function Ping-Host {
#Parameter Definition
Param (
[Parameter(position = 0)] $Hosts,
[Parameter] $ToCsv
)
#Funtion to make space so that formatting looks good
Function Make-Space($l,$Maximum) {
$space =""
$s = [int]($Maximum - $l) + 1
1..$s | %{$space+=" "}
return [String]$space
}
#Array Variable to store length of all hostnames
$LengthArray = #()
$Hosts | %{$LengthArray += $_.length}
#Find Maximum length of hostname to adjust column witdth accordingly
$Maximum = ($LengthArray | Measure-object -Maximum).maximum
$Count = $hosts.Count
#Initializing Array objects
$Success = New-Object int[] $Count
$Failure = New-Object int[] $Count
$Total = New-Object int[] $Count
cls
#Running a never ending loop
while ($true) {
$i = 0 #Index number of the host stored in the array
$out = "| HOST$(Make-Space 4 $Maximum)| STATUS | SUCCESS | FAILURE | ATTEMPTS |"
$Firstline=""
1..$out.length | %{$firstline+="_"}
#output the Header Row on the screen
Write-Host $Firstline
Write-host $out -ForegroundColor White -BackgroundColor Black
$Hosts | %{
$total[$i]++
if (Test-Connection $_ -Count 1 -Quiet -ErrorAction SilentlyContinue) {
$success[$i]+=1
#Percent calclated on basis of number of attempts made
$SuccessPercent = $("{0:N2}" -f (($success[$i]/$total[$i])*100))
$FailurePercent = $("{0:N2}" -f (($Failure[$i]/$total[$i])*100))
#Print status UP in GREEN if above condition is met
Write-Host "| $_$(Make-Space $_.Length $Maximum)| UP$(Make-Space 2 4) | $SuccessPercent`%$(Make-Space ([string]$SuccessPercent).length 6) | $FailurePercent`%$(Make-Space ([string]$FailurePercent).length 6) | $($Total[$i])$(Make-Space ([string]$Total[$i]).length 9)|" -BackgroundColor Green
} else {
$Failure[$i]+=1
#Percent calclated on basis of number of attempts made
$SuccessPercent = $("{0:N2}" -f (($success[$i]/$total[$i])*100))
$FailurePercent = $("{0:N2}" -f (($Failure[$i]/$total[$i])*100))
#Print status DOWN in RED if above condition is met
Write-Host "| $_$(Make-Space $_.Length $Maximum)| DOWN$(Make-Space 4 4) | $SuccessPercent`%$(Make-Space ([string]$SuccessPercent).length 6) | $FailurePercent`%$(Make-Space ([string]$FailurePercent).length 6) | $($Total[$i])$(Make-Space ([string]$Total[$i]).length 9)|" -BackgroundColor Red
}
$i++
}
#Pause the loop for few seconds so that output
#stays on screen for a while and doesn't refreshes
Start-Sleep -Seconds 10
cls
}
}
Ping-Host '10.50.5.33'
ConvertTo-HTML is the simple answer here but first you need to have object based output. Currently you are just outputting text to the console with Write-Host. In order to make that work you are doing some fancy formatting footwork which unfortunately is useless if you are just going to be outputting to HTML.
You can change this if you want but I didnt like the idea of while($true) since it will break the natural creation of the HTML Table. Obviously you are entitled to do what you want but this should be a working version that almost duplicates what you have. If you want to do some formatting I recommend you look up html styles.
Function Ping-Hosts{
param(
[string[]]$hosts,
[int]$MaxPings=100
)
# Hashtable that will record ongoing statistics
$results = $hosts | ForEach-Object{
#{
$_ = #{
Successes = 0
Attempts = 0
}
}
}
1..$MaxPings | ForEach-Object{
# Ping each computer a maximumn number of times.
$pingCount = $_
$hosts | ForEach-Object{
# Clear output statistics
$props = #{
Host = $_
Status = "Down" # Assume it's down.
}
# Perform a single ping
if (Test-Connection $_ -Count 1 -Quiet -ErrorAction SilentlyContinue){
# Success
$results.$_.Successes = $results.$_.Successes + 1
$props.Status = "UP"
}
# Raise the number of attempts
$results.$_.Attempts = $results.$_.Attempts + 1
# Calculate statistics
If($results.$_.Successes -eq 0){
$props.Success = "{0:p2}" -f 0
} else {
$props.Success = "{0:p2}" -f ($results.$_.Attempts / $results.$_.Successes)
}
If($results.$_.Attempts - $results.$_.Successes -eq 0){
$props.Failure = "{0:p2}" -f 0
} else {
$props.Failure = "{0:p2}" -f ($results.$_.Attempts / ($results.$_.Attempts - $results.$_.Successes))
}
$props.Attempts = $results.$_.Attempts
# Output results.
New-Object -TypeName psobject -Property $props
}
}
}
Sample execution
Ping-Hosts "c4222","C4280" | ConvertTo-Html -Fragment
Partial Sample Output
<tr><th>Host</th><th>Status</th><th>Attempts</th><th>Failure</th><th>Success</th></tr>
<tr><td>c4222</td><td>UP</td><td>1</td><td>0.00 %</td><td>100.00 %</td></tr>
<tr><td>C4280</td><td>UP</td><td>1</td><td>0.00 %</td><td>100.00 %</td></tr>
<tr><td>c4222</td><td>UP</td><td>2</td><td>0.00 %</td><td>100.00 %</td></tr>
<tr><td>C4280</td><td>UP</td><td>2</td><td>0.00 %</td><td>100.00 %</td></tr>
Closer to what you wanted
If you want something other than this I would look into css formatting closer. This is not the way I would have done it but have a look. You are complicating things by asking for the extra headers as you go (maybe there is a better way but we are off topic enough for this question)
Function Ping-Hosts{
param(
[string[]]$hosts,
[int]$MaxPings=100
)
# Hashtable that will record ongoing statistics
$results = $hosts | ForEach-Object{
#{
$_ = #{
Successes = 0
Attempts = 0
}
}
}
1..$MaxPings | ForEach-Object{
# Ping each computer a maximumn number of times.
$pingCount = $_
$hosts | ForEach-Object{
# Clear output statistics
$props = #{
Host = $_
Status = "Down" # Assume it's down.
}
# Perform a single ping
if (Test-Connection $_ -Count 1 -Quiet -ErrorAction SilentlyContinue){
# Success
$results.$_.Successes = $results.$_.Successes + 1
$props.Status = "UP"
# Set the backround color
$colour = "#2FFF18"
} else {
# Set the backround color
$colour = "#FF2020"
}
# Raise the number of attempts
$results.$_.Attempts = $results.$_.Attempts + 1
$props.Attempts = $results.$_.Attempts
# Calculate statistics
If($results.$_.Successes -eq 0){
$props.Success = "{0:p2}" -f 0
} else {
$props.Success = "{0:p2}" -f ($results.$_.Attempts / $results.$_.Successes)
}
If($results.$_.Attempts - $results.$_.Successes -eq 0){
$props.Failure = "{0:p2}" -f 0
} else {
$props.Failure = "{0:p2}" -f ($results.$_.Attempts / ($results.$_.Attempts - $results.$_.Successes))
}
# Output results.
$frag = New-Object -TypeName psobject -Property $props | ConvertTo-Html -Fragment
$frag -replace "<tr><td>","<tr bgcolor=$colour><td>"
}
}
}
Sample Call
Ping-Hosts "c4222","3" -MaxPings 2 | Set-Content c:\temp\test.html
Sample Output

Is it possible to output subsequent information to same line

I have a script that pings an ip address and send that information to a console window. In the case of high ping times or missed pings, it is also written to a log. I would like to keep only the high ping times and missed pings in the console window and allow the good pings to overwrite each other. Is that possible?
For high ping times, this is the output (similar code is used for missed pings).
$out = ("{0}ms at $(get-date -format G)" -f $ping.ResponseTime)
write-host $out -foregroundcolor "yellow"
$out >> .\runningPing$ipAddress.txt
For normal ping times, the output is this.
$out ("{0}ms" -f $ping.ResponseTime)
write-host $out -foregroundcolor "green"
I'd like to make that last line just overwrite itself for normal pings, but let the high and missed pings push up the screen as the program runs. Is that something I can do in PS?
SOLUTION
Thanks to #Mathias R. Jensen, I came up with this solution:
if ($ping.statuscode -eq 0) {
if ($ping.responsetime -gt $waitTime) {
$highPings = $highPings + 1
$out = ("{0}ms at $(get-date -format G)" -f $ping.ResponseTime)
[console]::SetCursorPosition(0,$highPings + $droppedPings + 1)
write-host $out -foregroundcolor "yellow"
$out >> $outFile
}
else {
$out = ("{0}ms $i of $pingCount" -f $ping.ResponseTime)
[console]::SetCursorPosition(0,$highPings + $droppedPings + 2)
write-host $out -foregroundcolor "green"
}
}
else {
$droppedPings = $droppedPings + 1
$out = ("missed ping at $(get-date -format G)")
[console]::SetCursorPosition(0,$highPings + $droppedPings + 1)
write-host $out -foregroundcolor "red"
$out >> $outFile
}
I think you should use Write-Progress for the good pings. You don't need to give a percentage, and you can use the -Status parameter to show just the last good one.
Here's a small example I wrote that might demonstrate how it would look/operate (you can execute this yourself to see, it doesn't ping anything it's just a simulation):
$goods = 0
0..100 | % {
if ((Get-Random -Minimum 0 -Maximum 100) -ge 50) {
$goods += 1
Write-Progress -Activity Test -Status "Last good ping: $_ ($goods total good pings)"
} else {
Write-Warning "Bad ping"
}
Start-Sleep -Seconds 1
}
In this case you could have even calculated, for example a percentage of good pings and used that in Write-Progress but I wanted to show that you don't need to use it as a progress bar for it to be useful.
As I mentioned in the comments, the cursor position can be controlled by this method:
[control]::SetCursorPosition([int]$x,[int]$y)
The [console] type accelerator points to the same Console class that enables you to WriteLine() to the console in a C# console application. You can also control colors and other console behavior if you feel like it:
Clear-Host
[console]::ForegroundColor = "Red"
1..10|%{
[console]::SetCursorPosition(2+$_,$_-1)
[console]::WriteLine("Hello World!")
}
[console]::ForegroundColor = "Green"
briantist has the better approach to this but I was playing around and came up with this as well. It will not work in ISE but should do it's job on the PowerShell console. It uses "`b" which is the backspace character so that the text will overwrite itself on the console host write. Might not help you but could be useful to others.
switch($ping.ResponseTime){
{$_ -ge 0 -and $_ -le 100}{
$out = "{0}ms" -f $_
$options = #{ForegroundColor = "Green"; NoNewline = $true}
$backup = "`b" * $out.Length
}
{$_ -ge 500 -and $_ -le 900}{
$out = "{0}ms at $(get-date -format G)" -f $_
$options = #{ForegroundColor = "Yellow"; NoNewline = $false}
$backup = "`n"
}
}
Write-Host "$backup$out" #options
Uses a switch to set the options based on the the range of ping times. Sets a small hash table which is splatted to the write-host. Not perfect but it shows another way to do it.
Again this mostly done for fun.

IIS 7.5 Application Pools / IIS Manager GUI column: Applications

When looking in the IIS 7.5 manager > application pools, The last column lists "Applications". This column shows the number of application pools / websites this appPool is associated with.
I am trying to figure out how to query this column / information using Powershell. The end goal here is to have a script that I could run that would tell me if any applicaiton pool is being used for more than 1 website or app.
I am unable to find how to query this information, when running:
get-itemproperty IIS:\AppPools\(AppPoolName) | format-list *
I dont see this property. Im not sure that this column is a property, if not, is there a best way to check if AppPools are being used for more than 1 website / applicaiton?
The Applications property is defined in the format file, its code reside in the iisprovider.format.ps1xml file (in the webadmin module folder).
<TableColumnItem>
<ScriptBlock>
$pn = $_.Name
$sites = get-webconfigurationproperty "/system.applicationHost/sites/site/application[#applicationPool=`'$pn`'and #path='/']/parent::*" machine/webroot/apphost -name name
$apps = get-webconfigurationproperty "/system.applicationHost/sites/site/application[#applicationPool=`'$pn`'and #path!='/']" machine/webroot/apphost -name path
$arr = #()
if ($sites -ne $null) {$arr += $sites}
if ($apps -ne $null) {$arr += $apps}
if ($arr.Length -gt 0) {
$out = ""
foreach ($s in $arr) {$out += $s.Value + "`n"}
$out.Substring(0, $out.Length - 1)
}
</ScriptBlock>
</TableColumnItem>
You can take the code out and use it outside the format file, just assign $pn the apppool name you want to query. Here's a simplified version of the code:
$pn = 'pool1'
$sites = get-webconfigurationproperty "/system.applicationHost/sites/site/application[#applicationPool='$pn' and #path='/']/parent::*" machine/webroot/apphost -name name
$apps = get-webconfigurationproperty "/system.applicationHost/sites/site/application[#applicationPool='$pn' and #path!='/']" machine/webroot/apphost -name path
$sites,$apps | foreach {$_.value}
I went with this:
Import-Module WebAdministration
function Get-WebAppPoolApplications($webAppPoolName) {
$result = #()
$webAppPool = Get-Item ( Join-Path 'IIS:\AppPools' $webAppPoolName )
if ( $webAppPool -ne $null ) {
$webSites = Get-ChildItem 'IIS:\Sites'
$webSites | % {
$webApplications = Get-ChildItem ( Join-Path 'IIS:\Sites' $_.Name ) |
where { $_.NodeType -eq 'application' }
$result += $webApplications |
where { $_.applicationPool -eq $webAppPoolName }
}
}
$result
}
Wish I would have seen your post earlier, this is what I eventually came up with:
$SiteApps = get-item IIS:\Sites* $arraySize = ($SiteApps.count -1)
$i = 0
$t = 0
for ($i=0; $i -le $arraySize; $i ++) # start at the beg of the array
{
for ($t=($i+1); $t -le $arraySize; $t++)
{
if ($siteApps[$i].applicationpool -eq $siteApps[$t].applicationpool)
{
$web1 = $siteApps[$i].name
$webappPool = $siteApps[$i].applicationpool
$web2 = $siteApps[$t].name $answer = $answer + "The website "$web1" is sharing the AppPool "webAppPool" with website "$web2". "
}
}
}