I have been trying to create a line of code to ping a range of IP addresses, in the windows command prompt, and after it finishes save the results in a text file. I am using a for loop to do the pinging, but I can't figure out how to save the results in a text file.
This is what I am using:
for /l %i in (1,1,64) do #ping 10.39.63.%i -w 1500 -n 1 | find "Reply"
I tried using the following code to save results in a text file, but it only saves the last command performed by CMD:
for /l %i in (1,1,64) do #ping 10.39.63.%i -w 100 -n 1 | find "Reply" >C:\Users\brymed\Desktop\test.txt
I want to keep it simple, so it'd be awesome to use only a line of code, but I am open to suggestions. Thank you.
This is not difficult using PowerShell. The $Hosts variable is a list of IP addresses to ping. The results are written to a file.
$Hosts = #()
foreach ($i in 1..64) { $Hosts += "10.39.63.$i" }
Test-Connection -Count 1 $hosts |
Select-Object -Property Address,BufferSize,Latency,Status |
Out-File -FilePath "$Env:USERPROFILE/Desktop/test.txt" -Encoding ascii
If you -must- run this in cmd.exe, the code can be formatted to do so.
pwsh.exe -NoLogo -NoProfile -Command ^
"$Hosts = #();" ^
"foreach ($i in 1..64) { $Hosts += \"10.39.63.$i\" };" ^
"Test-Connection -Count 1 $hosts -ErrorAction SilentlyContinue |" ^
"Select-Object -Property Address,BufferSize,Latency,Status |" ^
"Out-File -FilePath "$Env:USERPROFILE/Desktop/test.txt" -Encoding ascii"
Get PowerShell Core from https://github.com/PowerShell/PowerShell
Related
I have a folder on a shared network drive with a large number of text files. I am required to list the file name, size and number of lines/ rows in each file. I am able to use command prompt to get the output separately but I cannot seem to combine.
This works perfectly to list the file name and size:
DIR /s “files location*.txt” > Directory.txt
This works to for the line count:
for %f in ("files location*.txt" ) do find /v /c "" "%f"
I tried the following to combine but the output was empty and the command prompt window showed the full file location and name but without the line count
DIR /s “files location*.txt” | for %f in (“files location*.txt”) do find /v /c "" "%f" > Directory.txt
I think this question has been here before. Put these two (2) files into the same directory. The directory should be in the PATH variable. Many things could be done to make this more flexible using parameters. If you are on a supported Windows system, PowerShell will be available. If you have PowerShell 6 or higher, change powershell to pwsh.
=== Get-FileLineCount.bat
#ECHO OFF
powershell -NoLogo -NoProfile -File "%~dp0Get-FileListCount.ps1"
EXIT /B
=== Get-FileLineCount.ps1
Get-ChildItem -File -Path 'C:\src\t' -Filter '*.txt' |
ForEach-Object {
[PSCustomObject]#{
LastWriteTime = $_.LastWriteTime
Length = $_.Length
LineCount = (Get-Content -Path $_.FullName | Measure-Object).Count
FileName = $_.FullName
}
}
This produces the following output.
LastWriteTime Length LineCount FileName
------------- ------ --------- --------
2021-04-08 08:14:59 3 1 C:\src\t\abc.txt
2021-04-08 08:16:39 8 1 C:\src\t\abc-utf-8.txt
2019-07-08 11:38:36 30 1 C:\src\t\append.txt
2019-07-08 11:38:36 36 12 C:\src\t\appendtemp.txt
2020-03-06 09:48:51 104 25 C:\src\t\Combined.txt
I was looking for a more efficient way to delete all credentials stored in Credential Manager without having to delete credentials one by one. After few hours of browsing, I have finally stumbled upon this command prompt string that does exactly what I need:
for /F "tokens=1,2 delims= " %G in ('cmdkey /list ^| findstr Target') do cmdkey /delete %H
Since my knowledge of this syntax is quite limited, I would like to know what each of its section actually means. I already know what cmdkey /list, findstr and cmdkey /delete do but I am not sure about the rest.
Moreover, I would like to know how to make exceptions. For instance, in this case the line deletes all the strings that have a target as displayed in cmdkey list:
cmdkey.exe /list example
What if I want to make an exception and delete only some credentials but not other? Could I do that using the Type value instead of the Target value, for instance by asking the command prompt to delete only the Generic type credentials and not the Generic Certificate and the Domain Password type credentials?
Thanks in advance for your help.
KR,
Andy
When using the string "for /F "tokens=1,2 delims= " %G in ('cmdkey /list ^| findstr Target') do cmdkey /delete %H", I keep getting "CMDKEY: Element not found."
Therefore I scripted a quite primitive workaround since I do not know batch syntax so well. The script below puts together all the lines that have to be run in cmd to delete the corresponding CM keys. The last command in the script, invokes the file with all the lines. You have to just copy/paste them in a cmd and hit enter and it removes most of them:
$cachedCredentials = cmdkey /list
$CMCredentialsTxt = "C:\temp\CMCredentials.txt"
$cachedCredentials | Out-File $CMCredentialsTxt
(Get-Content $CMCredentialsTxt) | ? {$_.trim() -ne "" } | Set-Content $CMCredentialsTxt
(Get-Content $CMCredentialsTxt).Trim() | Set-Content $CMCredentialsTxt
(Get-Content $CMCredentialsTxt).Replace("Currently stored credentials:","") | Set-Content $CMCredentialsTxt
(Get-Content $CMCredentialsTxt).Replace("Type: Generic", "") | Set-Content $CMCredentialsTxt
(Get-Content $CMCredentialsTxt).Replace("User: App Info","") | Set-Content $CMCredentialsTxt
(Get-Content $CMCredentialsTxt).Replace("Local machine persistence","") | Set-Content $CMCredentialsTxt
(Get-Content $CMCredentialsTxt).Replace("Target: ","") | Set-Content $CMCredentialsTxt
(Get-Content $CMCredentialsTxt).Replace("User: <Certificate>","") | Set-Content $CMCredentialsTxt
(Get-Content $CMCredentialsTxt).Replace("Certificate","") | Set-Content $CMCredentialsTxt
(Get-Content $CMCredentialsTxt).Replace("User: User DT","") | Set-Content $CMCredentialsTxt
(Get-Content $CMCredentialsTxt).Replace("User: User OS Info","") | Set-Content $CMCredentialsTxt
(Get-Content $CMCredentialsTxt) | ? {$_.trim() -ne "" } | Set-Content $CMCredentialsTxt
$cleanTargets = Get-Content $CMCredentialsTxt
Remove-Item $CMCredentialsTxt
forEach ($cleanTarget in $cleanTargets){"cmdkey /delete:" + $cleanTarget | Out-File $CMCredentialsTxt -Append}
Invoke-Item $CMCredentialsTxt
I'm looking for a script that can be run from command line (batch \ PowerShell) that will go over a folder and its sub folders and will return a number which is a length of the longest file path.
I already saw some batch and PowerShell scripts like
How do I find files with a path length greater than 260 characters in Windows?
but none of them works satisfy my request.
Note that it's possible that file path will be more than 256 characters
PowerShell:
((Get-ChildItem -Recurse).FullName | Measure-Object -Property Length -Maximum).Maximum
Command line:
powershell -exec Bypass -c "((dir -rec).FullName | measure Length -max).Maximum"
Edit
related to error: Get-ChildItem : The specified path, file name, or both are too long: read Maximum Path Length Limitation and related [PowerShell]-tagged StackOverflow threads.
PS D:\PShell> ((Get-ChildItem "D:\odds and ends" -Directory -Recurse).FullName | Measure-Object -Property Length -Maximum).Maximum
242
PS D:\PShell> ((Get-ChildItem "D:\odds and ends" -Recurse -ErrorAction SilentlyContinue).FullName | Measure-Object -Property Length -Maximum).Maximum
242
Note that -ErrorAction SilentlyContinue in above command merely suppresses displaying of error messages. However, I know that the latter 242 value returned is wrong.
My workaroud applies cmd /C dir /B /S instead of (Get-ChildItem -Recurse).FullName as follows:
PS D:\PShell> $x = (. cmd /C dir /B /S "D:\odds and ends")
PS D:\PShell> $y = ( $x | Measure-Object -Property Length -Maximum).Maximum
PS D:\PShell> $y
273
PS D:\PShell> $z = $x | Where-Object { $_.Length -gt 260 }
PS D:\PShell> $z.GetTypeCode()
String
PS D:\PShell> $z
D:\odds and ends\ZalohaGogen\WDElements\zalohaeva\zaloha_honza\Music\Jazz\!Kompilace\Saint Germain des Pres Cafe Vol. 1 to 8 - The Finest Electro Jazz Complication\Saint Germain Des Pres Cafe Vol. 7 - The Finest Electro Jazz Complication\CD 1\Configuring and Using Inte.txt
PS D:\PShell>
Powershell is definitely not one of my "strengths" but every once in a while I try to script something to automate a manual task. Anyway, here is my problem. The script as is WORKS and WILL export a csv file and sort by the Hostname header. My issues is there has got to be a better way of doing this?
#Clear the output screen
cls
#set the working directory to where the script and text files are located (must be same directory)
$scriptdir = Split-Path -Parent $PSCommandPath
cd $scriptdir
#set fileNamePaths for Export-Csv No Sort and Sorted to excel
$FilePathNS = "D:\PowerShell_Scripts\HP_Inventory\OAInfoAll_NoSort.csv"
$FilePathSort = "D:\PowerShell_Scripts\HP_Inventory\OAInfoAll.csv"
#set up the ip subnet import
$path = ".\EnclosureSubnets.txt"
$ip = Get-Content $path
#Loop to find OA information
foreach ($subnet in $ip) {
$OAS = Find-HPOA $subnet -Timeout 250 -Verbose
$OAS | where {$_.Role -eq "Active"} | Export-Csv -NoTypeInformation -Append $FilePathNS
}
#Sort AOInfoAll.csv by hostname
Import-Csv $FilePathNS | Sort-Object Hostname | Export-Csv $FilePathSort -NoTypeInformation
If I take out the append then the loop will overwrite the previous entry and I will only end up with 2 IPs and 2 Hostnames. Append fixes this BUT when I run the script again I get duplicate/repeating entries.
Also, I've tried using the Sort-Object Hostname inside the loop but it only sorts each individual entry as they are written. Here is an example (IPs and Hostnames are made up):
IP Hostname
192.168.1.10 chassis03
192.168.1.12 chassis05
192.168.2.16 chassis01
192.168.2.18 chassis02
192.168.3.14 chassis07
192.168.3.16 chassis08
So while my script works I'd like some feedback from "The Pros" Thanks in advance!
Don't export inside your loop, instead capture all capture all OAS in a variable and sort that before outputting to a CSV.
foreach ($subnet in $ip) {
[array]$OAS += Find-HPOA $subnet -Timeout 250 -Verbose
}
$OAS | Where{$_.Role -eq 'Active'} | Sort Hostname | Export-Csv $FilePathSort -NoTypeInformation
That dramatically reduces the number of disk reads/writes.
I am writing a super-easy script in PowerShell. The target of this script is to read a list of server names from a txt file and a command block from another txt file. The result of the operation shold be a third txt file containing the information.
Here some code:
cls
$usr = Read-Host "Please insert username, you'll be asked for password later"
$path = Read-Host "Insert a valid path for ServerList.txt file"
$serverList = Get-Content -Path $path | Out-String
$path = Read-Host "Insert a valid path fom Command.txt file"
$commandBlock = Get-Content -Path $path | Out-String
echo "Command: " $commandBlock "will be executed on " $serverList
echo "Press CTRL+Z to abort or"
pause
Invoke-Command -ComputerName $serverList -ScriptBlock { $commandBlock } -credential $usr
Serverlist.txt is a plain text containing something like "server1,server2,server3" and command.txt contain only this "Get-WmiObject Win32_BIOS | Select-Object SerialNumber"
Why the error is Invoke-Command : One or more computer names are not valid. If you are trying to pass a URI, use the -ConnectionUri parameter, or pass URI objects
instead of strings. ?
I even tried to substitute $serverlist with $serverlist.toString() but it's not working. I read somewhere that in this case $serverlist is an Array, how do I do to make everything work?
Consider that https://technet.microsoft.com/en-us/library/hh849719.aspx Invoke-Commands work with "server1,server2,server3" format if you put the string via console.
Your $serverList isn't a list, it's a single string of server1,server2 etc. To make it into an array, you can use -split to split the string by commas.
$serverList = Get-Content -Path $path | Out-String
$serverList = $serverList -split ","
For further understanding of why this doesn't work as you expect, please see the parsing and command syntax help files:
Get-Help about_Parsing
Get-Help about_Command_Syntax
$serverlist
When your text file contains the line server1,server2,server3, this command:
Get-Content -Path .\file.txt | Out-String
Just results in the string server1,server2,server3 and a newline - that's not a valid hostname.
Either format your text file like this (Get-Content automatically splits on line breaks):
server1
server2
server3
or split the string(s) from the file yourself:
$Serverlist = Get-Content -Path $Path | ForEach-Object { $_ -split "," }
$commandblock
For the command block part to work, you can't just drop a string into a ScriptBlock and expect it to execute - you need to recreate it as executable code:
$Code = Get-Content -Path $path -Raw
$CommandBlock = [scriptblock]::Create($Code)
# Now you can do this
Invoke-Command -ScriptBlock $CommandBlock