将powershell脚本嵌入至bat文件中----修改指定窗口位置和大小
如何从批处理文件执行Powershell命令?多行注释
在批处理文件中执行PowerShell命令,可以使用powershell
命令行工具。以下是一个简单的批处理文件示例,它执行了一个PowerShell命令来显示当前目录下的文件和文件夹列表:
如果你有一个更复杂的PowerShell命令或脚本,你可以直接将它写在powershell -Command
后面。例如,以下批处理脚本执行了一个简单的PowerShell脚本,该脚本打印出“Hello, World!”:
如果你的PowerShell命令或脚本存储在一个文件中(比如script.ps1
),你可以使用-File
参数来执行它:
请确保你的批处理文件和PowerShell脚本文件的路径正确,并且批处理文件有适当的权限来执行PowerShell命令。
=======================================================================================
根据上面的,其实还有一个运行方式,和第一种差不多,利用管道符运行powershell命令
rem 执行powershell文件里的代码 type xxx.ps1 | powershell -command "-" rem 直接执行powershell代码 echo get-childitem | powershell -command "-"
=======================================================================================
单个bat中调用powershell 代码----多行注释法
1. 来源
How to execute powershell commands from a batch file?
kapitanrum 的回答:https://stackoverflow.com/a/41986771
2. PowerShell项目介绍
PowerShell/PowerShell: PowerShell 是由微软开发的命令行外壳程序和脚本环境,支持任务自动化和配置管理。它包含了丰富的.NET框架功能,适用于Windows和多个非Windows平台,提供了一种强大而灵活的方式来控制和自动执行系统管理任务。3. 思路
bat中注释使用rem
或::
,而powershell单行注释用#
,多行注释用<##>
,这一差异可以轻松将ps1脚本转为bat后缀的脚本,而不需要做大量的改动。
提示:在bat中:是个空命令,返回状态为0。
要想在bat脚本中运行powershell命令,需要使用powershell.exe的-Command
参数。幸运的是,ps1中你可以使用Invoke-Command
(别名icm
)来运行scriptblock,所以我们只需要将脚本文本通过[scriptblock]::Create()
做一个简单的转换就好了。
具体可在powershell命令行中查看帮助:help icm
4. 代码
如果脚本编码不同,设置Get-Content
读取时的编码,或者用[IO.File]
类指定编码格式读取脚本.
<# :
@powershell "icm ([scriptblock]::Create((gc '%~f0' -Raw -Encoding UTF8)))"
@exit/b
#>
Write-Host "Hello World" -fore Red
pause
# powershell script
2024-11-06 15:41:09【出处】:https://blog.csdn.net/qq_41755979/article/details/107370596
=======================================================================================
将powershell脚本嵌入至bat文件中
背景
将Powershell脚本嵌入至bat文件中可以有很多意想不到的收获,比如可以通过这个方式绕过授权,或者简化脚本的运行,或者可以便于复杂参数的配置
原理
这里是使用了一个投巧夺做法,使用findstr跳过@开头顶行,然后使用powershell的换行符^拼接powershell命令,最后通过powershell -command执行命令。
具体操作
@ECHO off
@setlocal EnableDelayedExpansion
@goto label1
@echo this lines should not be printed
@echo and this whole block (lines 4-8) can actually be removed
@echo I added these just for DoubleWen
@:label1
@set LF=^
@SET command=#
@chcp 65001 > nul
@FOR /F "tokens=*" %%i in ('findstr -bv @ "%~f0"') DO SET command=!command!!LF!%%i
@powershell -noprofile -command !command! & goto:eof
# *** POWERSHELL CODE STARTS HERE *** #
Write-Host '中文测试完美' -Fore red;
Write-Host 'This is PowerShell code being run from inside a batch file!' -Fore red;
$PSVersionTable;
Get-Process -Id $PID | Format-Table;
2024-11-06 15:40:11【出处】:https://blog.csdn.net/tcliuwenwen/article/details/117935243
=======================================================================================
使用批处理直接运行PowerShell脚本
背景:
作为一名苦逼的运维岗,需要经常写PowerShell脚本,自己写自己用,完美闭环,这本来没什么问题,但是由于项目、公司等等一系列的变更需求,这些脚本需要分发给普通用户使用,由于PowerShell脚本的运行有局限性,用户使用会有各种各样的问题,因此研究通过批处理直接运行PowerShell脚本。
思路:
1、考虑到易用性,给用户的必须是单个文件,因此通过批处理直接打开PowerShell脚本文件的方法行不通;
2、由于批处理涉及写入、删除等动作,因此批处理运行时需要自动提权;
3、PowerShell的运行依赖电脑的安全策略,默认不能运行,因此需要变更执行策略,使得电脑可以运行PowerShell脚本;
方法:
1、批处理中提权:
%1 start "" mshta vbscript:createobject("shell.application").shellexecute("""%~0""","::",,"runas",1)(window.close)&exit/b
注:使用%1开头,是为了第二次执行的时候,使用::把该句注释掉,否则会循环执行,也可换成rem注释
2、变更电脑的执行策略,使得能够执行Powershell脚本:
PowerShell -Command "Set-ExecutionPolicy RemoteSigned -Scope CurrentUser"
3、批处理中通过“more”命令跳过指定的行数,生成PowerShell脚本,生成完成之后再执行Powershell脚本,示例:
more +2 %0 > ps.ps1
Powershell -File "ps.ps1"
4、及时删除生成的PowerShell文件:
Remove-Item $MyInvocation.MyCommand.Path -Force
示例:
1 @echo off 2 %1 start "" mshta vbscript:createobject("shell.application").shellexecute("""%~0""","::",,"runas",1)(window.close)&exit/b 3 cd /d %~dp0 4 PowerShell -Command "Set-ExecutionPolicy RemoteSigned -Scope CurrentUser" 5 more +9 %0 > psScripts.ps1 6 Powershell -File "psScripts.ps1" 7 pause&goto :eof 8 9 10 # *** POWERSHELL CODE STARTS HERE *** # 11 Remove-Item $MyInvocation.MyCommand.path -Force 12 Write-Host '中文测试完美' -Fore red; 13 Write-Host 'This is PowerShell code being run from inside a batch file!' -Fore red; 14 $PSVersionTable; 15 Get-Process -Id $PID | Format-Table; 16 Write-Host "Hello,$env:USERNAME,看到这句话说明执行成功了,按回车键退出。。。" -ForegroundColor yellow -NoNewline 17 Read-Host
代码说明:
第5行是跳过前9行,就是把第9行之后的代码写入psScripts.ps1文件中
第6行是执行powershell文件
第7行是暂停和跳过剩下的代码,跳转到文件末尾。
第10行开始是powershell代码,自行添加自己的代码
第11行的删除ps1文件也可以换到最后一行。
上面的知识给出一个框架,具体根据自己需要进行修改和调整代码。
2024-11-06 15:53:41【出处】:https://blog.csdn.net/u011226383/article/details/128318755
=======================================================================================
bat和powershell混合编程
if ($true){}# == ($true){}# goto ___yiwuyun <# :___yiwuyun @echo off setlocal cls rem 查找要滑过的行数,行数加2 rem for /f "tokens=1 delims=:" %%a in ('findstr /N "^::__yiwuyunSigned" "%~f0"') do set /a lineCount=%%a+2 rem 设置执行策略 powershell -command "&{set-executionPolicy remoteSigned}" rem 执行powershell脚本 rem type "%~f0"|more +%lineCount%|powershell -command "-" type "%~f0"|powershell -command "-" rem 恢复执行策略 powershell -command "&{set-executionPolicy restricted}" pause exit/b 0 rem 签名表示要滑过的行数 ::__yiwuyunSigned #> <#PowerShell脚本文件体#> Function DeleteFileByFileName{ Param([string]$FileName) if(Test-Path $FileName -PathType leaf){Remove-Item $FileName} } $strPath=(Resolve-Path ".\").Path; DeleteFileByFileName -FileName ($strPath+"\test.xlsx"); $objExcel=New-Object -ComObject "Excel.Application" $objExcel.WorkBooks.Add().SaveAs($strPath+"\test.xlsx"); $objExcel.DisplayAlerts=$false; $objExcel.visible=$true; $objExcel.SheetsInNewWorkBook=2; $strArray=New-Object -TypeName System.Collections.ArrayList; $strArray.Add("姓名")|Out-Null; $strArray.Add("数学")|Out-Null; $strArray.Add("外语")|Out-Null; $strArray.Add("历史")|Out-Null; $strArray.Add("化学")|Out-Null; $strArray.Add("生物")|Out-Null; for($col=1;$col -lt 7;$col++){ $objExcel.ActiveSheet.Cells.Item(1,$col)=$strArray[$col-1]; } for($row=2;$row -lt 11;$row++){ $objExcel.ActiveSheet.Cells.Item($row,1)="A$row"; } $objExcel.Range("B2:F10").Formula="=40+Int(Rand()*61)"; $objExcel.Range("A1:F10").Style.HorizontalAlignment=-4108; $objShape=$objExcel.ActiveSheet.Shapes.AddChart(51); $objShape.Chart.SetSourceData($objExcel.Range("A1:F10"),2); $objExcel.ActiveWorkBook.Save(); ##$objExcel.Quit();
出处:http://www.bathome.net/thread-34884-1-1.html
个人修改和调整
上面的代码设置和恢复执行策略的时候,发现会报错,主要是上面修改的策略是计算机的,我加上了-Scope CurrentUser,修改当前用户的执行策略便可以正常了,如下:
rem 设置执行策略
powershell -command "&{set-executionPolicy remoteSigned -Scope CurrentUser}"
rem 恢复执行策略
powershell -command "&{set-executionPolicy restricted -Scope CurrentUser}"
使用more的语句,会截断输出,如上面的rem type "%~f0"|more +%lineCount%|powershell -command "-",所以最好还是使用:type "%~f0"|powershell -command "-"
注意!!!如果是使用:type "%~f0"|powershell -command "-" 的方式,需要在注释bat脚本的结尾,既在#>的后面保留一个空行。
=======================================================================================
[其他] bat,vbs,js,powershell混合编程
一直想写个VBS,JS,BAT混合编程的范例,但始终找不到重写源文件名的方法,虽然sed能实现,但总是第三方软件,所以未能动笔,最近学了下PS,顺便就把这几个混合起来了。
理论上,任何脚本语言,只要有exe的引擎,就可以通过powershell和bat混合,从而实现所有脚本的混合编程。因此,SED,GAWK所写的脚本都能和VBS,JS,POWERSHELL混
编。不多说,上范例。
if ($true){}# == ($true){}# goto ___yiwuyun <#BeginBatOperation# :___yiwuyun @echo off&setlocal&cls (echo $yiwuyun_fileName="%~f0"&echo $strPath="%~dp0"&type "%~f0")|powershell -command - pause exit/b 0 #EndBatOperation#> <#StartPowerShell#> "正在运行JScript"; $js_content=gc $yiwuyun_fileName; for($i=0;$i -lt $js_content.count;$i++){ if($js_content[$i] -match "^<#StartJS#"){$StartJS_Line=$i+1;} if($js_content[$i] -match "^#EndJS#>"){$EndJS_Line=$i-1;break;} } for($i=$StartJS_Line;$i -le $EndJS_Line;$i++){ $js+=$js_content[$i]+"`r`n"; } out-file -FilePath $yiwuyun_fileName -Encoding "OEM" -InputObject $js; cscript //nologo //e:jscript $yiwuyun_fileName; out-file -FilePath $yiwuyun_fileName -Encoding "OEM" -InputObject $js_content; "正在运行VBScript"; $vbs_content=gc $yiwuyun_fileName; for($i=0;$i -lt $vbs_content.count;$i++){ if($vbs_content[$i] -match "^<#StartVBS#"){$StartVBS_Line=$i+1;} if($vbs_content[$i] -match "^#EndVBS#>"){$EndVBS_Line=$i-1;break;} } for($i=$StartVBS_Line;$i -le $EndVBS_Line;$i++){ $vbs+=$vbs_content[$i]+"`r`n"; } out-file -FilePath $yiwuyun_fileName -Encoding "OEM" -InputObject $vbs; cscript //nologo //e:vbscript $yiwuyun_fileName; out-file -FilePath $yiwuyun_fileName -Encoding "OEM" -InputObject $vbs_content; <#EndPowerShell#> <#StartJS# var str="abcdefgBC12bC34"; var patt=new RegExp(/(B)(c)/ig);/* js中的索引从0开始,与C语言一致 var patt=new ReExp("BC","g");*/ var result; var strMatch=""; while((result=patt.exec(str))!=null){ for(var i=0;i<result.length;i++){ if(i==0){ strMatch=strMatch+"match: "+result[i]+" "+"index:"+result.index; }else{ strMatch=strMatch+" "+i+":"+result[i]; } } strMatch=strMatch+" all:"+result.input+" patt.lastIndex:"+patt.lastIndex; WScript.Echo(strMatch); strMatch=""; } #EndJS#> <#StartVBS# Dim objExcel,strArray(6) strPath=Left(WScript.ScriptFullName,InStrRev(WScript.ScriptFullName,"\")) Set objExcel=CreateObject("Excel.Application") 'objExcel.WorkBooks.Add.SaveAs(strPath&"test.xlsx") DeleteFileByFilename(strPath&"test.xlsx") objExcel.WorkBooks.Add().SaveAs(strPath&"test.xlsx") objExcel.DisplayAlerts=false objExcel.visible=true objExcel.SheetsInNewWorkBook=2 strArray(0)="姓名" strArray(1)="数学" strArray(2)="外语" strArray(3)="历史" strArray(4)="化学" strArray(5)="生物" For col=1 to 6 objExcel.WorkBooks("test.xlsx").ActiveSheet.Cells(1,col).value=strArray(col-1) 'objExcel.Cells(1,col).value=strArray(col-1) Next For row=2 to 10 objExcel.Cells(row,1).value=String(1,65)+CStr(row) Next objExcel.Range("B2:F10").Formula="=40+Int(Rand()*61)" objExcel.Range("A1:F10").Style.HorizontalAlignment=-4108 Set objShape=objExcel.ActiveSheet.Shapes.AddChart(51) objShape.Chart.SetSourceData objExcel.Range("A1:F10"),2 Set objShape=Nothing 'objExcel.ActiveSheet.SaveAs(strPath&"test.xlsx") objExcel.ActiveWorkBook.Save objExcel.Quit() Sub DeleteFileByFilename(FullFilename) Dim objFSO Set objFSO=WScript.CreateObject("Scripting.FileSystemObject") If objFSO.FileExists(FullFilename) Then 'call objFSO.DeleteFile(FullFilename,True) objFSO.DeleteFile FullFilename,True End If Set objFSO=Nothing End Sub #EndVBS#>
出处:http://www.bathome.net/thread-34983-1-1.html
=======================================================================================
个人使用
可以按照上面的逻辑,编写bat代码:
if ($true){}# == ($true){}# goto __runBat <#BeginBatOperation# :__runBat @echo off&setlocal&cls (echo $yiwuyun_fileName="%~f0"&echo $strPath="%~dp0") (type "%~f0")|powershell -command - pause&exit/b 0 #EndBatOperation#> # *** POWERSHELL CODE STARTS HERE *** # Write-Host "`n`n Powershell开始运行!" -Fore red;
以下是powershell代码,可以直接附加在上面的bat代码的后面就可以了!
Add-Type @" using System; using System.Runtime.InteropServices; public class Win32 { [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint); [DllImport("user32.dll")] public static extern uint FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); public const uint SWP_NOSIZE = 0x1; public const uint SWP_NOMOVE = 0x2; public const uint SWP_SHOWWINDOW = 0x40; public const uint wndInsertAfter = 0x0; [DllImport("user32")] public static extern int GetSystemMetrics(int nIndex); [DllImport("user32")] public static extern void SwitchToThisWindow(IntPtr hWnd,bool fAltTab); } "@ # 查找记事本窗口的句柄"wmware-view.exe","FC-JC" $winHandle = [Win32]::FindWindow($null, '无标题 - 记事本') $winHandle = [Win32]::FindWindow("wmware-view.exe",$null) $winHandle = [Win32]::FindWindow($null,"FC-JC") $winHandle = @(Get-Process -name "vmware-view")[0].MainWindowHandle echo winHandle=$winHandle # 获取屏幕大小 $w = [Win32]::GetSystemMetrics(0) $h = [Win32]::GetSystemMetrics(1)-40 echo w=$w,h=$h # 移动记事本窗口到屏幕上的(100,100)位置,并设置窗口大小为400x400 #[Win32]::MoveWindow($winHandle, 0, 0, $w, $h, $false) [Win32]::SetWindowPos($winHandle, [IntPtr]::Zero, 0, 0, $w, $h, [Win32]::SWP_SHOWWINDOW) [Win32]::SwitchToThisWindow($winHandle,$true) # $notepadWindow = Get-Process notepad -ErrorAction SilentlyContinue | ForEach-Object { Get-WindowHandle -ProcessId $_.Id } # foreach ($window in $notepadWindow) { # [Win32]::SetWindowPos($window, [IntPtr]::Zero, 0, 0, 0, 0, [Win32]::SWP_NOSIZE, [Win32]::SWP_NOMOVE, [Win32]::SWP_SHOWWINDOW) # } return; #使用Windows API调整当前命令行窗口大小和位置 $code=@' using System; using System.Runtime.InteropServices; public static class WinApi{ [DllImport("user32.dll")] public static extern bool SetWindowPos(uint hWnd,uint hAfter,uint x,uint y,uint cx,uint cy,uint flags); [DllImport("user32.dll")] public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); } '@ Add-Type -TypeDefinition $code #设置位置及大小 $hwnd = [WinApi]::GetConsoleWindow() [void][WinApi]::SetWindowPos($hwnd,$null,30,30,400,500,0) echo =====================
关注我】。(●'◡'●)
如果,您希望更容易地发现我的新博客,不妨点击一下绿色通道的【因为,我的写作热情也离不开您的肯定与支持,感谢您的阅读,我是【Jack_孟】!
本文来自博客园,作者:jack_Meng,转载请注明原文链接:https://www.cnblogs.com/mq0036/p/18530347
【免责声明】本文来自源于网络,如涉及版权或侵权问题,请及时联系我们,我们将第一时间删除或更改!