Get date and time on the same line - powershell

I can use date /t and time /t to get the date and time, but it doesn't display it next to each other. I wanted to make it do that and display like this:
Current Date & Time
-------------------
11/27/2013 10:43:05 AM

Try the following (PowerShell):
Get-Date -Format G
27.11.2013 17:10:23
The format is defined with the system's regional settings, so for me this is what I get, but if you're regional date/time format is what you want, it should show up like you want.
(Get-Date).ToString()
would probably also work.
UPDATE:
"Date and time is: $((Get-Date).ToString())"

In PowerShell this is trivial:
(Get-Date).ToString('MM/dd/yyyy hh:mm:ss tt')
In cmd it's somewhat complicated:
rem Get the date and time in a locale-agnostic way
for /f %%x in ('wmic path win32_localtime get /format:list ^| findstr "="') do set %%x
rem Leading zeroes for everything that could be only one digit
set Month=0%Month%
set Day=0%Day%
rem Hours need special attention if one wants 12-hour time (who wants that?)
if %Hour% GEQ 12 (set AMPM=PM) else (set AMPM=AM)
set /a Hour=Hour %% 12
if %Hour%==0 (set Hour=12)
set Hour=0%Hour%
set Minute=0%Minute%
set Second=0%Second%
set Month=%Month:~-2%
set Day=%Day:~-2%
set Hour=%Hour:~-2%
set Minute=%Minute:~-2%
set Second=%Second:~-2%
rem Now you can just create your output string
echo %Month%/%Day%/%Year% %Hour%:%Minute%:%Second% %AMPM%
Note that lots of code is wasted on supporting that weird date and time format. And leading zeroes if necessary. Note also that this code works regardless of the user's regional and language settings. It does not depend on the user's date format, for example (which for me is ISO 8601 anyway).

I am no wizard with cmd.exe, but this works. There may be an easier way!
#echo off
setlocal enableextensions
for /f "tokens=*" %%a in ('date /t') do (
set d=%%a
)
for /f "tokens=*" %%a in ('time /t') do (
set t=%%a
)
REM Add those puppies together
set "dt=%d% %t%"
echo %dt%
27/11/2013 16:04

For CMD, Why not the simple:
C:\temp\test>ECHO %DATE% %TIME%
Mon 06/24/2019 18:00:17.63
If you want to strip off the Day at the beginning, here's a condensed version of what Joey did, using substrings.
for /f "delims=" %%a in ('wmic OS Get localdatetime ^| find "."') do set dt=%%a
set timestamp=%dt:~0,4%/%dt:~4,2%/%dt:~6,2% %dt:~8,2%:%dt:~10,2%:%dt:~12,2%
ECHO %timestamp%
2019/06/24 17:56:43
2019/06/24 17:56:43

You can use as well the .NET DateTime in powershell:
Write-Host "Current datetime is $([System.Datetime]::Now.ToString("dd/MM/yy HH:mm:ss"))"

thank you all i was looking for inline date and time column string.
#date time sample
Select-Object #{ l='DateTime'; e={ (Get-Date).tostring("yyyyMMddHHmm")} }
here is the full script below. for remote query
do {
$MHEdate = (Get-Date).tostring("yyyyMMddHHmmss") # example output 20161122.
$OutputDir = "C:\tools\pshell\LOG\"
$logoname = 'getcoonections-filter-' + $MHEdate1 + '.csv'
$OutputFile1 = Join-Path $OutputDir $logoname
Invoke-Command -ComputerName ServerName {
#output to csv
get-nettcpconnection | select local*,remote*,state,#{Name="Process";Expression={(Get-Process -Id $_.OwningProcess).ProcessName}},#{Name="ProcessID";Expression={(Get-Process -Id $_.OwningProcess).Id}}| Where-Object {($_.RemoteAddress -notcontains '0.0.0.0') -and ($_.RemoteAddress -notcontains '127.0.0.1') -and ($_.RemoteAddress -notcontains '::') -and ($_.RemoteAddress -notcontains '::1')} #|Where-Object{ $_.remoteaddress -Contains '168.135.115.248'}
# start-sleep -Seconds 15
}| Select-Object #{ l='DateTime'; e={ (Get-Date).tostring("yyyyMMddHHmm")} },PSComputerName,LocalAddress,LocalPort,RemoteAddress,RemotePort,State,Process,ProcessID | Export-Csv -Path $OutputFile1 -NoTypeInformation -Append
#Import-Csv $OutputFile1 |Out-GridView
write-host -ForegroundColor Green $Time "query output file is ---> " $OutputFile1
Start-Sleep 120
}until($infinity)

Related

Windows 10 Registry SubKey REG_MULTI_SZ How do I edit just some of the values

Good Morning,
I could use help, I'm trying to edit just some of the values of a REG_MULTI_SZ using PowerShell but I'm not having any luck.
The Key is: HKLM\SOFTWARE\Bentley\BentleyDesktopClient\Install
And the original value of the key is:
KeyName_CheckUpdateOption=
KeyName_CheckUpdateOptionModTime=<number-varies>
KeyName_UpdateClientInstallTime=<number-varies>
KeyName_CheckUpdateIsEnabled=1
(depending on the install, the values KeyName_CheckUpdateOptionModTime=<some-number> and KeyName_UpdateClientInstallTime=<some-number> will be different.)
I want the end result after editing to be:
KeyName_CheckUpdateOption=3
KeyName_CheckUpdateOptionModTime=<number-varies>
KeyName_UpdateClientInstallTime=<number-varies>
KeyName_CheckUpdateIsEnabled=0
But the best I've been able to come up with is replacing all the data with just one line with this script:
REG ADD HKLM\SOFTWARE\Bentley\BentleyDesktopClient\Install /t REG_MULTI_SZ /v "UpdateClient" /d "Keyname_CheckUpdateOption=3"
So the result I get is:
So the question is, how can I replace just SOME of the values in a Multi-String key, and preserve the rest and their order?
I would like to then create a Batch file so I can run this on multiple pc's.
I really appreciate everyone's time and assistance, Thank You.
You could use switch for this like below:
$regPath = 'HKLM:\SOFTWARE\Bentley\BentleyDesktopClient\Install'
$oldValue = (Get-ItemPropertyValue -Path $regPath -Name 'UpdateClient') -ne ''
$newValue = switch -Wildcard ($oldValue) {
'KeyName_CheckUpdateOption=*' { 'KeyName_CheckUpdateOption=3' }
'KeyName_CheckUpdateIsEnabled=*' { 'KeyName_CheckUpdateIsEnabled=0' }
default { $_ } # return this item unchanged
}
Set-ItemProperty -Path $regPath -Name 'UpdateClient' -Value $newValue
The new content of the registry value will be:
KeyName_CheckUpdateOption=3
KeyName_CheckUpdateOptionModTime=<number-varies>
KeyName_UpdateClientInstallTime=<number-varies>
KeyName_CheckUpdateIsEnabled=0
This may be too much code lines of powershell, but it works for me:
Clear-Host
$currentProperty = (Get-ItemProperty -Path Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Bentley\BentleyDesktopClient\Install | Select-Object -ExpandProperty "UpdateClient")
#You may need this to compare in the future
$newProperty = $currentProperty
#Searching value KeyName_CheckUpdateOption. If value set - replace it, if not - set it
$CurrentKeyName_CheckUpdateOption = $null
$CurrentKeyName_CheckUpdateOption = ($newProperty | Select-String -Pattern 'KeyName_CheckUpdateOption=([0-9.]+)')
if($CurrentKeyName_CheckUpdateOption.Matches.Value) {
Write-Output $CurrentKeyName_CheckUpdateOption.Matches.Value
$newProperty = $newProperty.Replace("$($CurrentKeyName_CheckUpdateOption.Matches.Value)","KeyName_CheckUpdateOption=3")
} else {
$newProperty = $newProperty.Replace("KeyName_CheckUpdateOption=","KeyName_CheckUpdateOption=3")
}
#Same for KeyName_CheckUpdateIsEnabled.
$CurrentKeyName_CheckUpdateIsEnabled = $null
$CurrentKeyName_CheckUpdateIsEnabled = ($newProperty | Select-String -Pattern 'KeyName_CheckUpdateIsEnabled=([0-9.]+)')
if($CurrentKeyName_CheckUpdateIsEnabled.Matches.Value) {
$newProperty = $newProperty.Replace("$($CurrentKeyName_CheckUpdateIsEnabled.Matches.Value)","KeyName_CheckUpdateIsEnabled=0")
} else {
$newProperty = $newProperty.Replace("KeyName_CheckUpdateIsEnabled=","KeyName_CheckUpdateIsEnabled=0")
}
# Set updated value to registry
Set-ItemProperty -Path HKLM:\SOFTWARE\Bentley\BentleyDesktopClient\Install -Name UpdateClient -Value $newProperty
Just for the sake of your batch-file tag, here's something which does not use powershell.exe, and which still uses your used reg.exe utility.
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
Set "MultiStr="
For /F "EOL=H Tokens=2,*" %%G In ('%SystemRoot%\System32\reg.exe Query "HKLM\SOFTWARE\Bentley\BentleyDesktopClient\Install" /V "UpdateClient" 2^>NUL') Do Set "MultiStr=%%H"
If Not Defined MultiStr GoTo :EOF
For /F "Delims==" %%G In ('"(Set _Item[) 2>NUL"') Do Set "%%G="
Set "i=1"
SetLocal EnableDelayedExpansion
Set "_Item[%i%]=%MultiStr:\0=" & Set /A i += 1 & Set "_Item[!i!]=%"
Set "MultiStr="
If Not Defined _Item[1] (EndLocal & GoTo :EOF)
For /F "Tokens=1-3 Delims==" %%G In ('"(Set _Item[) 2>NUL"') Do If "%%H" == "KeyName_CheckUpdateOption" (If /I Not "%%I" == "3" Set "%%G=%%H=3") Else If "%%H" == "KeyName_CheckUpdateIsEnabled" If /I Not "%%I" == "0" Set "%%G=%%H=0"
For /F "Tokens=1,* Delims==" %%G In ('"(Set _Item[) 2>NUL"') Do If Not Defined MultiStr (Set "MultiStr=%%H") Else Set "MultiStr=!MultiStr!\0%%H"
If Not Defined MultiStr (EndLocal & GoTo :EOF)
%SystemRoot%\System32\reg.exe Add "HKLM\SOFTWARE\Bentley\BentleyDesktopClient\Install" /V "UpdateClient" /T REG_MULTI_SZ /D "!MultiStr!" /F 1>NUL
EndLocal
GoTo :EOF
The basic idea is that it reads the registry value data, separates it into list items, checks each list item for the key pairs, adjusting as necessary, rebuilds the data, and adds it back to the registry.
Please note that as this is modifying a Local Machine Key, it will need to be 'Run as administrator'/elevated.
Caveat: this script will only maintain the multi-string item order if there are nine items or less

Is there a way to get a subtracted date from Powershell in a batch file?

I'm trying to create a .bat file get the current business day-1, so if it's Monday the date should be the Friday date(current date -3), if it's Friday the date should be Thursday date(current date -1). I can get the dates from Powershell but when i try to get the date with the subtraction it gives me this error:
get-date was unexpected at this time.
This is generated in the last part of the powershell command in bold text:
if %WEEKDAY%==3 (for /f %%i in ('powershell $dataAtual=get-date;$dataAtual=$dataAtual.AddDays(-3); **get-date** $dataAtual') do set FX=%%i) else (set FX=%CURRENTDATE%)
echo %FX%
I tried to remove the get-date so it just prints the value of $dataAtual like in powershell but it them says:
$dataAtual was unexpected at this time
Full code:
for /f %%i in ('powershell get-date -f yyy.MM.dd') do set CURRENTDATE=%%i
echo %CURRENTDATE%
for /f %%i in ('powershell get-date %CURRENTDATE% -UFormat %%u') do set WEEKDAY=%%i
echo %WEEKDAY%
if %WEEKDAY%==3 (for /f %%i in ('powershell $dataAtual=get-date;$dataAtual=$dataAtual.AddDays(-3); get-date $dataAtual') do set FX=%%i) else (set FX=%CURRENTDATE%)
echo %FX%
(I know weekday 3 is not Friday in the code above, I'm just testing for now)
Refer to the Theo's Comment , You can write it into a batch file like this :
#echo off
set psCmd="&{$dataAtual=(Get-Date).AddDays(-1); while (1..5 -notcontains $dataAtual.DayOfWeek) { $dataAtual = $dataAtual.AddDays(-1) }; get-date $dataAtual -f yyyy.MM.dd}"
Call :RunPS %psCmd% FX
Echo %FX%
pause & Exit
::----------------------------------------------------------------------
:RunPS <PassPSCMD> <RetValue>
#for /F "usebackq tokens=*" %%i in (`Powershell %1`) do set "%2=%%i"
Goto:eof
:: End of :RunPS function
::----------------------------------------------------------------------

How to get the folder name with highest number in folder name?

I have multiple folders with these names:
ABC_03_00_016_0
ABC_03_00_016_1
ABC_03_00_016_2
ABC_03_00_016_3
ABC_03_00_016_4
ABC_03_00_016_5
What I want to do is to retain the folder with largest number in the end of folder name, i.e. ABC_03_00_016_5 in above case using PowerShell or batch commands.
How to get the folder with greatest number?
Maybe this could be done more elegant, but it's probably working as you want. I'm stripping the last digits, converting & comparing them to then determine the highest one. As you can see, order does not matter:
$items =
"ABC_03_00_016_0",
"ABC_03_00_016_100",
"ABC_03_00_016_99"
[int]$highestNumberTillNow = 0
$highestitem = ""
foreach ($item in $items){
[int]$number = $item.substring($item.LastIndexOf("_")+1,$item.length-$item.LastIndexOf("_")-1)
if ($number -gt $highestNumberTillNow){
$highestNumberTillNow = $number
$highestitem = $item
}
}
write-host $highestitem
You can use this:
#echo off
setlocal enabledelayedexpansion
pushd "%~dp0"
for /f "tokens=4 delims=_" %%a in ('dir ABC_03_016_* /ad /b') do (
for /f "tokens=* delims= " %%b in ('dir ABC_03_016_* /ad /b') do (
set dir[%%a]=%%b
)
)
set dc=0
:loop
set /a dc=dc+1
if defined dir[%dc%] goto loop
goto break
:break
set /a dc=dc-1
echo The folder is !dir[%dc%]!
pause >nul
Assuming you could have more folders with a similar name in the root path like
ABC_03_00_016_0
ABC_03_00_016_1
ABC_03_00_016_2
ABC_03_00_016_3
ABC_03_00_016_4
ABC_03_00_016_5
DEF_03_00_016_0
DEF_03_00_016_1
DEF_03_00_016_10
Using PowerShell you can use something like below.
This will return the folder object(s) with the highest number at the end of the name:
$lastFolder = Get-ChildItem -Path 'D:\test' -Directory | Where-Object { $_.Name -match '(.+)_(\d+)$' } |
Group-Object -Property #{Expression={ $matches[1] }} | ForEach-Object {
$_.Group | Sort-Object -Property #{Expression={ [int]$matches[2] }} | Select-Object -Last 1
}
# for demo, just output the FullName property of the folders found
$lastFolder.FullName
Output:
D:\test\ABC_03_00_016_5
D:\test\DEF_03_00_016_10
Regex details:
( Match the regular expression below and capture its match into backreference number 1
. Match any single character that is not a line break character
+ Between one and unlimited times, as many times as possible, giving back as needed (greedy)
)
_ Match the character “_” literally
( Match the regular expression below and capture its match into backreference number 2
\d Match a single digit 0..9
+ Between one and unlimited times, as many times as possible, giving back as needed (greedy)
)
$ Assert position at the end of the string (or before the line break at the end of the string, if any)
If you're wanting to remove all of the directories except for the one ending with the largest number, then I'd suggest PowerShell too:
Get-ChildItem -Path 'C:\Users\Naqqash\Desktop' -Filter '*_*_*_*_*' -Directory |
Where-Object { $_.Name -Match '(.+)_(\d+)$' } |
Sort-Object -Property { [Int]$($_.Name).Split('_')[-1] } |
Select-Object -SkipLast 1 |
Remove-Item
Please remember to adjust the path on line 1 to that holding your directories.
The example above requires PowerShell v5.0
The first method can be used only if all folder names have the same length, i.e. leading zeros are used to make sure that all numbers in all folder names have same number of digits.
#echo off
set "LastFolder="
for /F "eol=| delims=" %%I in ('dir "%~dp0ABC_03_00_016_*" /AD /B /O-N 2^>nul') do set "LastFolder=%%I" & goto HaveFolder
echo Found no folder matching pattern ABC_03_00_016_* in "%~dp0".
goto :EOF
:HaveFolder
echo Last folder according to sorted folder names is: %LastFolder%
The task to get folder name with greatest last number is more difficult on number of digits differs on last number.
#echo off
set "LastFolder="
setlocal EnableExtensions EnableDelayedExpansion
set "FolderNumber=-1"
for /F "eol=| delims=" %%I in ('dir "%~dp0ABC_03_00_016_*" /AD /B 2^>nul') do (
for /F "eol=| tokens=5 delims=_" %%J in ("%%I") do (
if %%J GTR !FolderNumber! (
set "LastFolder=%%I"
set "FolderNumber=%%J"
)
)
)
endlocal & set "LastFolder=%LastFolder%"
if not defined LastFolder (
echo Found no folder matching pattern ABC_03_00_016_* in "%~dp0".
) else (
echo Last folder according to last number in name is: %LastFolder%
)
Note: The last number in folder name should have never leading zeros on using the second code above. A number with one or more leading 0 is interpreted as octal number which means 08, 09, 18, 19, etc. are invalid octal numbers and are interpreted for that reason with value 0 by command IF on making the integer comparison. There would be additional code necessary above the IF condition to first remove all leading 0 from number string before doing the integer comparison.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /? ... explains %~dp0 (drive and path of batch file ending with a backslash).
dir /?
echo /?
endlocal /?
for /?
if /?
set /?
setlocal /?
Read the Microsoft article about Using command redirection operators for an explanation of 2>nul. The redirection operator > must be escaped with caret character ^ on FOR command line to be interpreted as literal character when Windows command interpreter processes this command line before executing command FOR which executes the embedded dir command line with using a separate command process started in background.

Padleft function with a sequence number in PowerShell

I need to add a progressive number of fixed length at the beginning of each row in a txt file. For example:
0001 aaaaaaaaaaa
0002 bbbbbbbbbb
...
0010 gggggggggg
I created a .bat file to run a PowerShell which should solve the problem:
#echo off &setlocal
set "path=C:\Users..."
set "filein=%~1"
set "fileout=%filein%_out"
setlocal EnableDelayedExpansion
call %SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe -Command "& {(Get-Content %path%\%filein%.txt) |ForEach-Object {$_.Insert(0,($id++).PadLeft(10,'0'))} |Set-Content %path%\%fileout%.txt}"
But it doesn't work. Probably there's some syntax error.
($id++).PadLeft(10,'0') fails, because ($id++) is of type [int], not [string], and [int] has no .PadLeft() method.
Simply converting ($id++) to a string is enough:
($id++).ToString().PadLeft(10,'0')
Also note that your sample output has a space between the padded number and the content of the line, so you'd have to use:
$_.Insert(0, ($id++).ToString().PadLeft(10,'0') + ' ')
As an aside:
You don't need call in a batch file to call executables (call is only needed for calling other batch files, if you want the call to return).
The PowerShell executable is in the %PATH% by default, so you can invoke it by name only, i.e., powershell.exe.
since you added the [batch-file] tag - here is a pure Batch solution:
#echo off
setlocal enabledelayedexpansion
set count=0
(for /f "delims=" %%A in (input.txt) do (
set /a count+=1
set "index=00000!count!"
echo !index:~-4! %%A
))>Output.txt
Something like this might workout for you -
$id = 1
$files = Get-Content "\\PathToYourFile\YourFile.txt"
foreach ($file in $files)
{
$Padded = $id.ToString("0000000000");
$file.Insert(0, ($Padded));
$id++
}
Use the ToString() method, instead of PadLeft to add progressive number of fixed length zeroes. That is much simpler and hassle-free.
Also, doing the entire operation in PowerShell will be much simpler.
You can also do this in a single line like -
$i = 1
Get-Content "\\PathToYourFile\YourFile.txt" | % { $_.Insert(0, ($i.ToString("0000000000"))); $i++ } | Set-Content ".\NewFileout.txt"
Here is a pure batch file solution, which does not ignore empty lines and is safe against all characters, even exclamantion marks (!):
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set /A "IDX=0"
> "output.txt" (
for /F "delims=" %%L in ('findstr /N "^" "input.txt"') do (
set /A "IDX+=0"
set "LINE=%%L"
setlocal EnableDelayedExpansion
set "IDX=0000!IDX!"
echo !IDX:~-4! !LINE:*:=!
endlocal
)
)
endlocal
exit /B

Use PowerShell to determine length of a line in a text file

I'm new to PowerShell, but I would like to use it, because there isn't a easy way to get the length of a string in Windows batch.
I need to write a piece of code in PowerShell that go through each line in a .txt file and determine the character length of that line. If the character length is over 250 then....etc.
The ....etc part is not important at the moment :)
In Windows batch I would write it like this:
FOR /F %%A IN ("C:\TestFile.txt") DO (
SET LINE=%%A
If LINE > 250 characters then ( ' This line is made up
....etc
)
How can I do it?
The following will do what you want:
$data = Get-Content "C:\TestFile.txt"
foreach($line in $data)
{
if ($line.Length -gt 250) {
Write-Host "A match"
}
}
Try this:
:: Not fully tested:
for /f "delims=" %%s in (C:\TestFile.txt) do (
set "x=%%s" & set /A y+=1
setlocal enabledelayedexpansion
for /f "skip=1 delims=:" %%i in ('"(set x&echo()|findstr /o ".*""') do set/a n=%%i-4
if !n! gtr 250 echo Line !y! Length !n!
endlocal
)
Was looking for this today and found an elegant solution here: https://softwarerecs.stackexchange.com/questions/38934/finding-the-longest-line-of-a-document/38936
GC "c:\folder\file.txt" | Measure -Property length -Maximum | Select Maximum
GC "c:\folder\file.txt" | Sort -Property length | Select -last 1
Important: credit goes to Pimp Juice IT from the link above, I'm just copy/pasting : )