I am trying to update one of the parameters of Windows Service (kubelet) by using this link
1. $regkey = "HKLM\SYSTEM\CurrentControlSet\Services\kubelet"
2. $name = "ImagePath"
3. $(reg query ${regkey} /v ${name} | Out-String) -match "(?s)${name}.*(C:.*kubelet\.exe.*)"
4. $kubelet_cmd = $Matches[1] -replace "--image-pull-progress-deadline=.* ","" -replace "\r\n"," "
5. reg add ${regkey} /f /v ${name} /t REG_EXPAND_SZ /d "${kubelet_cmd} --image-pull-progress-deadline=40m "
Step #3 output
PS C:\Users\Administrator> $(reg query ${regkey} /v ${name} | Out-String) -match "(?s)${name}.*(C:.*kubelet\.exe.*)"
True
Output of Steps 4 and 5
PS C:\Users\Administrator> $kubelet_cmd = $Matches[1] -replace "--image-pull-progress-deadline=.* ","" -replace "\r\n"," "
PS C:\Users\Administrator> reg add ${regkey} /f /v ${name} /t REG_EXPAND_SZ /d "${kubelet_cmd} --image-pull-progress-deadline=40m "
ERROR: Invalid syntax.
Type "REG ADD /?" for usage.
I am not sure which part of reg add is causing this error. Kindly let me know what am I doing wrong
EDIT
Output of $kubelet_cmd is given below
PS C:\Users\Administrator> echo $kubelet_cmd
C:\ProgramData\Kubernetes\kubernetes\node\bin\kubelet.exe --windows-service --v=6 --log-dir=C:\ProgramData\Kubernetes\logs\kubelet --cert-dir=C:\var\lib\kubelet\pki --cni-bin-dir=C:\ProgramData\Kubernetes\cni --cni-conf-dir=C:\ProgramData\Kubernetes\cni\config --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --hostname-override=WIN --pod-infra-container-image=mcr.microsoft.com/k8s/core/pause:1.2.0 --enable-debugging-handlers --cgroups-per-qos=false --enforce-node-allocatable="" --logtostderr=false --network-plugin=cni --resolv-conf="" --cluster-dns="10.96.0.10" --cluster-domain=cluster.local --feature-gates=
It appears some of the attributes have double-quotes which is causing the issue. But, not sure how to overcome this when executing Step #5
I resolved the steps by editing Windows registry
Opened Windows registry
Navigated to Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\kubelet hive
Right-click --> Modify on attribute ImagePath (on the right pane)
Added the parameter --image-pull-progress-deadline=50m
Restarted kubelet service using services.msc
Related
I am trying to create a bat file to run cmd code to save bitlockers numeric id to ad
the code I got that far is
#echo off
title bitlocker to AD.
echo Bitlocker to ActiveDirectory
pause
powershell -Command manage-bde -protectors -get c:
powershell -Command manage-bde -protectors c: -id {<numericalpassword>}
echo 1)Exit
set input=
set /p input= Choice
if %input%==2 goto Exit if NOT goto Start 2```
`
But what I got when I run it is:
[![what really happened][1]][1]
[1]: https://i.stack.imgur.com/uM3b9.png
basically it cannot recognize the "<numericalpassword>"
How to I get the numerical password id as a string that I can push to the second line?
I have tested in my environment
how to i get the numerical password id as a string that i can push to
the second line ?
You can use the below command to get the numerical password id as a string variablee :
$key = ((manage-bde -protectors -get c:) | Select-String -SimpleMatch "ID: ")[1] -replace "ID:","" -replace " ",""
Now you can use this variable in the second line as follows :
manage-bde -protectors -adbackup c: -id $key
Also, you can write the powershell script for the two powershell commands and run the script in the bat file.
Use the below powershell script :
$key = ((manage-bde -protectors -get c:) | Select-String -SimpleMatch "ID: ")[1] -replace "ID:","" -replace " ",""
manage-bde -protectors -adbackup c: -id $key
Save this script in your local and use this line in your bat file :
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& 'path-to-your-powershell-script'"
Instead of
powershell -Command manage-bde -protectors -get c:
powershell -Command manage-bde -protectors c: -id {<numericalpassword>}
I'm getting this when I try to run:
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& 'path-to-your-powershell-script'"
Output:
C:\Users>$key = ((manage-bde -protectors -get c:) | Select-String -SimpleMatch "ID: ")[1] -replace "ID:","" -replace " ",""
'$key' is not recognized as an internal or external command,
operable program or batch file.
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 am trying to make a Powershell script for uninstalling software.
Here is the code:
$software = Read-Host "Software you want to remove"
$paths = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
Get-ChildItem $paths |
Where-Object{ $_.GetValue('DisplayName') -match "$software" } |
ForEach-Object{
$uninstallString = $_.GetValue('UninstallString') + ' /quiet /norestart'
Write-Host $uninstallString
& "C:\Windows\SYSTEM32\cmd.exe" /c $uninstallString
}
it works good for uninstall strings like
MsiExec.exe /X{C22F57FC-4B20-3354-8626-382E3C710B38} /quiet /norestart
But if I want to uninstall something like winrar which have uninstall strings like
C:\Program Files\WinRAR\uninstall.exe
I get the following error
cmd.exe : 'C:\Program' is not recognized as an internal or external command,
any idea please how to get this script working
Regards
The problem is that you're unconditionally appending /quiet /norestart.
The solution is to test if the uninstall string as a whole refers to an executable file:
$isExeOnly = Test-Path -LiteralPath $uninstallString
Based on that, you can decide how you want to handle such executables:
If you simply want to execute them without arguments:
$uninstallString = $_.GetValue('UninstallString')
$isExeOnly = Test-Path -LiteralPath $uninstallString
if (-not $isExeOnly) { $uninstallString += ' /quiet /norestart' }
If you do want to pass arguments /quiet /norestart - though note that the target executable may refuse to execute if it doesn't understand these arguments:
$uninstallString = $_.GetValue('UninstallString')
$isExeOnly = Test-Path -LiteralPath $uninstallString
if ($isExeOnly) { $uninstallString = "`"$uninstallString`"" }
$uninstallString += ' /quiet /norestart'
The alternative is to special-case the arguments (options) to pass based on the executable file name (Split-Path -Leaf $uninstallString), but that is obviously cumbersome and impossible to do comprehensively.
Uninstall-package works with msi installs.
For non-msi installs:
You'd have to find out the silent uninstall options for winrar. It might be '/S'. (A quick google says it is.)
get-package *winrar* | % { & $_.metadata['uninstallstring'] /S }
Sometimes you have to get rid of literal double quotes:
get-package *winrar* | % { & ($_.metadata['uninstallstring'] -replace '"') /S }
Here's an attempt of a general answer for non-msi installs where part of the uninstallstring may or may not be in double-quotes:
$uninstall = get-package whatever | % { $_.metadata['uninstallstring'] }
$prog, $myargs = $uninstall | select-string '("[^"]*"|\S)+' -AllMatches |
% matches | % value
$prog = $prog -replace '"',$null
$myargs += '/S' # whatever silent uninstall option
& $prog $myargs
I want to dump all the file names in a folder without extension into a text file. They should be in one line separated by commas.
So in my folder I have
File1.bin
File2.bin
....
With
(for %%a in (.\*.bin) do #echo %%~na,) >Dump.txt
I got
File1,
File2,
But what I want in the end is a text file with, so one long combined string.
File1,File2,...
I'm kinda stuck here and probably need something else than echo.
Thanks for trying to help.
Try like this:
#echo off
setlocal enableDelayedExpansion
for %%a in (.\*.txt) do (
<nul set /p=%%~nxa,
)
check also the accepted answer here and the dbenham's one.
You could also leverage powershell from a batch-file for this task:
#"%__APPDIR__%WindowsPowerShell\v1.0\powershell.exe" -NoProfile -Command "( Get-Item -Path '.\*' -Filter '*.bin' | Where-Object { -Not $_.PSIsContainer } | Select-Object -ExpandProperty BaseName ) -Join ',' | Out-File -FilePath '.\dump.txt'"
This could probably be shortened, if necessary, to:
#PowerShell -NoP "(GI .\*.bin|?{!$_.PSIsContainer}|Select -Exp BaseName) -Join ','>.\dump.txt"
Based on How can I auto-elevate my batch file, so that it requests from UAC administrator rights if required? I'm trying to make an RunElevated.bat (see code below) that accepts a command-line (batch file name and parameters) as arguments.
The RunElevated.bat works fine when the target batch file path has no spaces in them. But it fails as soon as that path has spaces: no matter how I quote things, either PowerShell barfs, or the parameters are not passed correctly from PowerShell to the batch file.
I tried:
escaping with "" (as suggested by many sources)
escaping with \" (as suggested by Escaping quotes in powershell.exe -command via command prompt)
adding --% (as suggested by PowerShell and external commands done right and Easier Reuse of Command Lines From Cmd.exe)
surrounding with ' (as suggested by CB.).
So:
Is what I want to do possible at all?
If so: how?
RunElevated.bat:
:checkParameters
echo [%*]
if [%1]==[] ( goto :help ) else ( goto :checkPrivileges )
:help
echo Syntax:
echo %0 CmdLine
echo Where CmdLine is executed with UAC privileges.
goto :exit
:checkPrivileges
net file 1>nul 2>nul
if '%errorlevel%' == '0' ( goto :gotPrivileges ) else ( goto :getPrivileges )
:getPrivileges
PowerShell "Start-Process -FilePath \"%0\" -Verb RunAs -ArgumentList \"%*\""
goto :exit
:gotPrivileges
%*
pause
:exit
pause
exit /b
echo-cd.bat which I stored in both D:\tools\echo-cd.bat and "D:\to ols\echo-cd.bat":
echo Current Directory: [%CD%]
echo Parameters: [%*]
pause
This runs fine:
D:\tools\RunElevated.bat D:\tools\echo-cd.bat foo
These fail:
D:\tools\RunElevated.bat "D:\to ols\echo-cd.bat" foo
First failure is at the %*:
C:\Windows\system32>D:\to ols\echo-cd.bat foo
'D:\to' is not recognized as an internal or external command,
operable program or batch file.
This is because PowerShell removed the quotes around the batch file name:
C:\Windows\system32>echo [D:\to ols\echo-cd.bat foo]
[D:\to ols\echo-cd.bat foo]
I expected D:\to ols\echo-cd.bat to have double quotes around it, and foo not.
D:\tools\RunElevated.bat \"D:\to ols\echo-cd.bat\" foo
Second failure is at the PowerShell level:
D:\>PowerShell "Start-Process -FilePath \"D:\tools\RunElevated.bat\" -Verb RunAs -ArgumentList \"\"D:\to ols\echo-cd.bat\" foo\""
Start-Process : Cannot validate argument on parameter 'ArgumentList'. The argument is null or empty. Supply an argument that is not null or empty and then try the command again.
At line:1 char:77
+ Start-Process -FilePath "D:\tools\RunElevated.bat" -Verb RunAs -ArgumentList <<<< ""D:\to ols\echo-cd.bat" foo"
This is because escaping twice will end up with an empty string for ArgumentList.
D:\tools\RunElevated.bat --% "D:\to ols\echo-cd.bat" foo
Third failure is also at the %*:
C:\Windows\system32>--% D:\to ols\echo-cd.bat foo
'--%' is not recognized as an internal or external command,
operable program or batch file.
This too is because PowerShell removed the quotes around the batch file name:
C:\Windows\system32>echo [--% D:\to ols\echo-cd.bat foo]
[--% D:\to ols\echo-cd.bat foo]
I expected --% to be absent, D:\to ols\echo-cd.bat to have double quotes around it, and foo not.
D:\tools\RunElevated.bat '"D:\to ols\echo-cd.bat"' foo
Again a failure is at the %*:
C:\Windows\system32>'D:\to ols\echo-cd.bat' foo
The filename, directory name, or volume label syntax is incorrect.
This is because PowerShell removed the double quotes (and left the single quotes) around the batch file name:
C:\Windows\system32>echo ['D:\to ols\echo-cd.bat' foo]
['D:\to ols\echo-cd.bat' foo]
C:\Windows\system32>if ['D:\to] == [] (goto :help ) else (goto :checkPrivileges )
I recall using the following approach for this:
start "" %systemroot%\System32\windowspowerShell\v1.0\powershell.exe -exec bypass -noprofile -command "&{ start-process powershell -verb RunAs -ArgumentList '-noprofile -exec bypass -file \"c:\temp\test folder\elevatedpowershell.ps1\"'}"
You can replace \"c:\temp\test folder\elevatedpowershell.ps1\" with \"$0\" like you did there.
I also found the solution from Keith Hill on self elevating PowerShell to be useful if I need the person to be admin. I do not have the link now but it goes like this:
function IsAdministrator
{
$Identity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$Principal = New-Object System.Security.Principal.WindowsPrincipal($Identity)
$Principal.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)
}
function IsUacEnabled
{
(Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System).EnableLua -ne 0
}
if (!(IsAdministrator))
{
if (IsUacEnabled)
{
[string[]]$argList = #('-NoProfile', '-File', ('"' + $MyInvocation.MyCommand.Path + '"'))
$argList += $MyInvocation.BoundParameters.GetEnumerator() | Foreach {"-$($_.Key)", "$($_.Value)"}
$argList += $MyInvocation.UnboundArguments
Start-Process "$env:Windir\System32\WindowsPowerShell\v1.0\PowerShell.exe" -Verb Runas -WorkingDirectory $pwd -WindowStyle Hidden -ArgumentList $argList
return
}
else
{
throw "You must be administrator to run this script"
}
}
Assuming, you want to have elevated PowerShell script, you can have that at the top of your PowerShell script.
Ugly but it can do the job.
Use single quotes (or any character of your choice) and insert this in your code:
:gotPrivileges
cd "%~p0"
set arg=%*
set arg=%arg:'="%
%arg%
:: %*
pause
If you have 8.3 file names enabled you can try this:
:getPrivileges
setlocal enabledelayedexpansion
set Args=%*
for %%a in (%*) do if exist %%a (
set Args=!Args:%%a="%%~sa"!
)
PowerShell "Start-Process -FilePath \"%0\" -Verb RunAs -ArgumentList \"%Args%\"" 2>nul
goto :exit
However, if you pass an argument that happens to be the name of a file or folder (that exists relative to RunElevated.bat) it can get altered.