The response has been limited to 50k tokens of the smallest files in the repo. You can remove this limitation by removing the max tokens filter.
├── .editorconfig
├── .github
    ├── FUNDING.yml
    ├── ISSUE_TEMPLATE
    │   ├── bug_report.md
    │   └── feature_request.md
    └── workflows
    │   ├── run_reinstall.yml
    │   └── sync_to_cnb.yml
├── LICENSE
├── README.en.md
├── README.md
├── cloud-init-fix-onlink.sh
├── cloud-init.yaml
├── debian.cfg
├── fix-eth-name.initd
├── fix-eth-name.service
├── fix-eth-name.sh
├── frpc-example.toml
├── frpc.service
├── get-frpc-url.sh
├── get-xda.sh
├── initrd-network.sh
├── logviewer-nginx.conf
├── logviewer.html
├── redhat.cfg
├── reinstall.bat
├── reinstall.sh
├── resize.sh
├── trans.sh
├── ttys.sh
├── ubuntu-storage-early.sh
├── ubuntu.yaml
├── windows-allow-ping.bat
├── windows-change-rdp-port.bat
├── windows-del-gpo.bat
├── windows-driver-utils.sh
├── windows-frpc.bat
├── windows-frpc.xml
├── windows-resize.bat
├── windows-set-netconf.bat
├── windows-setup.bat
├── windows.xml
└── wmic.ps1


/.editorconfig:
--------------------------------------------------------------------------------
 1 | root = true
 2 | 
 3 | [*]
 4 | indent_style = space
 5 | indent_size = 4
 6 | end_of_line = lf
 7 | charset = utf-8
 8 | trim_trailing_whitespace = true
 9 | insert_final_newline = true
10 | 
11 | [{windows.xml,windows-*.xml}]
12 | end_of_line = crlf
13 | 
14 | [windows-frpc.xml]
15 | charset = utf-16-le
16 | indent_size = 2
17 | 
18 | [*.{bat,cmd,ps1}]
19 | end_of_line = crlf
20 | 
21 | [*.ps1]
22 | charset = utf-8-bom
23 | 
24 | [*.{yml,yaml}]
25 | indent_size = 2
26 | 


--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: bin456789
2 | 


--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | name: Bug report (问题反馈)
 3 | about: Create a report to help us improve
 4 | title: ''
 5 | labels: ''
 6 | assignees: ''
 7 | 
 8 | ---
 9 | 
10 | 原来的系统:
11 | 要安装的系统:
12 | 遇到的问题:截图或者登录 SSH 获取日志 /reinstall.log
13 | 
14 | Original system:
15 | System to be installed:
16 | Issues encountered: Screenshot or log in via SSH to get the logs from /reinstall.log
17 | 


--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | name: Feature request (功能请求)
 3 | about: Suggest an idea for this project
 4 | title: ''
 5 | labels: ''
 6 | assignees: ''
 7 | 
 8 | ---
 9 | 
10 | 
11 | 


--------------------------------------------------------------------------------
/.github/workflows/run_reinstall.yml:
--------------------------------------------------------------------------------
 1 | name: 运行主程序
 2 | on:
 3 |   workflow_dispatch:
 4 |   push:
 5 |     paths:
 6 |       - "reinstall.*"
 7 | jobs:
 8 |   run:
 9 |     name: 运行主程序
10 |     strategy:
11 |       matrix:
12 |         os: [ubuntu-latest, windows-latest]
13 |         include:
14 |           - os: ubuntu-latest
15 |             command: sudo bash reinstall.sh --debug --password 123@@@
16 |           - os: windows-latest
17 |             command: ./reinstall.bat --debug --password 123@@@
18 |     runs-on: ${{ matrix.os }}
19 |     steps:
20 |       - run: |
21 |           git config --global core.autocrlf false
22 |       - uses: actions/checkout@v4
23 |       - run: |
24 |           ${{ matrix.command }} centos
25 |           ${{ matrix.command }} almalinux 8
26 |           ${{ matrix.command }} rocky 9
27 |           ${{ matrix.command }} fedora
28 |           ${{ matrix.command }} ubuntu
29 |           ${{ matrix.command }} debian
30 |           ${{ matrix.command }} debian --ci
31 |           ${{ matrix.command }} kali
32 |           ${{ matrix.command }} alpine
33 |           ${{ matrix.command }} opensuse
34 |           ${{ matrix.command }} arch
35 |           ${{ matrix.command }} gentoo
36 | 
37 |           ${{ matrix.command }} netboot.xyz
38 |           ${{ matrix.command }} dd --img=https://download.opensuse.org/tumbleweed/appliances/openSUSE-MicroOS.x86_64-SelfInstall.raw.xz
39 |           ${{ matrix.command }} windows --image-name='Windows Server blah' --iso https://aka.ms/HCIReleaseImage
40 | 
41 |           # 测试失败例子
42 |           # ${{ matrix.command }} wrong-os
43 |           # ${{ matrix.command }} dd --img=https://github.com/
44 |           # ${{ matrix.command }} windows --iso=https://github.com/ --image-name=abc
45 | 


--------------------------------------------------------------------------------
/.github/workflows/sync_to_cnb.yml:
--------------------------------------------------------------------------------
 1 | name: 同步到 CNB
 2 | on:
 3 |   workflow_dispatch:
 4 |   push:
 5 | jobs:
 6 |   run:
 7 |     name: 同步到 CNB
 8 |     runs-on: ubuntu-latest
 9 |     steps:
10 |       - uses: actions/checkout@v4
11 |         with:
12 |           fetch-depth: 0
13 |       - uses: yesolutions/mirror-action@master
14 |         with:
15 |           REMOTE: https://cnb.cool/bin456789/reinstall.git
16 |           GIT_USERNAME: cnb
17 |           GIT_PASSWORD: ${{ secrets.CNB_TOKEN }}
18 |           PUSH_ALL_REFS: false
19 | 


--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
  1 |                     GNU GENERAL PUBLIC LICENSE
  2 |                        Version 3, 29 June 2007
  3 | 
  4 |  Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
  5 |  Everyone is permitted to copy and distribute verbatim copies
  6 |  of this license document, but changing it is not allowed.
  7 | 
  8 |                             Preamble
  9 | 
 10 |   The GNU General Public License is a free, copyleft license for
 11 | software and other kinds of works.
 12 | 
 13 |   The licenses for most software and other practical works are designed
 14 | to take away your freedom to share and change the works.  By contrast,
 15 | the GNU General Public License is intended to guarantee your freedom to
 16 | share and change all versions of a program--to make sure it remains free
 17 | software for all its users.  We, the Free Software Foundation, use the
 18 | GNU General Public License for most of our software; it applies also to
 19 | any other work released this way by its authors.  You can apply it to
 20 | your programs, too.
 21 | 
 22 |   When we speak of free software, we are referring to freedom, not
 23 | price.  Our General Public Licenses are designed to make sure that you
 24 | have the freedom to distribute copies of free software (and charge for
 25 | them if you wish), that you receive source code or can get it if you
 26 | want it, that you can change the software or use pieces of it in new
 27 | free programs, and that you know you can do these things.
 28 | 
 29 |   To protect your rights, we need to prevent others from denying you
 30 | these rights or asking you to surrender the rights.  Therefore, you have
 31 | certain responsibilities if you distribute copies of the software, or if
 32 | you modify it: responsibilities to respect the freedom of others.
 33 | 
 34 |   For example, if you distribute copies of such a program, whether
 35 | gratis or for a fee, you must pass on to the recipients the same
 36 | freedoms that you received.  You must make sure that they, too, receive
 37 | or can get the source code.  And you must show them these terms so they
 38 | know their rights.
 39 | 
 40 |   Developers that use the GNU GPL protect your rights with two steps:
 41 | (1) assert copyright on the software, and (2) offer you this License
 42 | giving you legal permission to copy, distribute and/or modify it.
 43 | 
 44 |   For the developers' and authors' protection, the GPL clearly explains
 45 | that there is no warranty for this free software.  For both users' and
 46 | authors' sake, the GPL requires that modified versions be marked as
 47 | changed, so that their problems will not be attributed erroneously to
 48 | authors of previous versions.
 49 | 
 50 |   Some devices are designed to deny users access to install or run
 51 | modified versions of the software inside them, although the manufacturer
 52 | can do so.  This is fundamentally incompatible with the aim of
 53 | protecting users' freedom to change the software.  The systematic
 54 | pattern of such abuse occurs in the area of products for individuals to
 55 | use, which is precisely where it is most unacceptable.  Therefore, we
 56 | have designed this version of the GPL to prohibit the practice for those
 57 | products.  If such problems arise substantially in other domains, we
 58 | stand ready to extend this provision to those domains in future versions
 59 | of the GPL, as needed to protect the freedom of users.
 60 | 
 61 |   Finally, every program is threatened constantly by software patents.
 62 | States should not allow patents to restrict development and use of
 63 | software on general-purpose computers, but in those that do, we wish to
 64 | avoid the special danger that patents applied to a free program could
 65 | make it effectively proprietary.  To prevent this, the GPL assures that
 66 | patents cannot be used to render the program non-free.
 67 | 
 68 |   The precise terms and conditions for copying, distribution and
 69 | modification follow.
 70 | 
 71 |                        TERMS AND CONDITIONS
 72 | 
 73 |   0. Definitions.
 74 | 
 75 |   "This License" refers to version 3 of the GNU General Public License.
 76 | 
 77 |   "Copyright" also means copyright-like laws that apply to other kinds of
 78 | works, such as semiconductor masks.
 79 | 
 80 |   "The Program" refers to any copyrightable work licensed under this
 81 | License.  Each licensee is addressed as "you".  "Licensees" and
 82 | "recipients" may be individuals or organizations.
 83 | 
 84 |   To "modify" a work means to copy from or adapt all or part of the work
 85 | in a fashion requiring copyright permission, other than the making of an
 86 | exact copy.  The resulting work is called a "modified version" of the
 87 | earlier work or a work "based on" the earlier work.
 88 | 
 89 |   A "covered work" means either the unmodified Program or a work based
 90 | on the Program.
 91 | 
 92 |   To "propagate" a work means to do anything with it that, without
 93 | permission, would make you directly or secondarily liable for
 94 | infringement under applicable copyright law, except executing it on a
 95 | computer or modifying a private copy.  Propagation includes copying,
 96 | distribution (with or without modification), making available to the
 97 | public, and in some countries other activities as well.
 98 | 
 99 |   To "convey" a work means any kind of propagation that enables other
100 | parties to make or receive copies.  Mere interaction with a user through
101 | a computer network, with no transfer of a copy, is not conveying.
102 | 
103 |   An interactive user interface displays "Appropriate Legal Notices"
104 | to the extent that it includes a convenient and prominently visible
105 | feature that (1) displays an appropriate copyright notice, and (2)
106 | tells the user that there is no warranty for the work (except to the
107 | extent that warranties are provided), that licensees may convey the
108 | work under this License, and how to view a copy of this License.  If
109 | the interface presents a list of user commands or options, such as a
110 | menu, a prominent item in the list meets this criterion.
111 | 
112 |   1. Source Code.
113 | 
114 |   The "source code" for a work means the preferred form of the work
115 | for making modifications to it.  "Object code" means any non-source
116 | form of a work.
117 | 
118 |   A "Standard Interface" means an interface that either is an official
119 | standard defined by a recognized standards body, or, in the case of
120 | interfaces specified for a particular programming language, one that
121 | is widely used among developers working in that language.
122 | 
123 |   The "System Libraries" of an executable work include anything, other
124 | than the work as a whole, that (a) is included in the normal form of
125 | packaging a Major Component, but which is not part of that Major
126 | Component, and (b) serves only to enable use of the work with that
127 | Major Component, or to implement a Standard Interface for which an
128 | implementation is available to the public in source code form.  A
129 | "Major Component", in this context, means a major essential component
130 | (kernel, window system, and so on) of the specific operating system
131 | (if any) on which the executable work runs, or a compiler used to
132 | produce the work, or an object code interpreter used to run it.
133 | 
134 |   The "Corresponding Source" for a work in object code form means all
135 | the source code needed to generate, install, and (for an executable
136 | work) run the object code and to modify the work, including scripts to
137 | control those activities.  However, it does not include the work's
138 | System Libraries, or general-purpose tools or generally available free
139 | programs which are used unmodified in performing those activities but
140 | which are not part of the work.  For example, Corresponding Source
141 | includes interface definition files associated with source files for
142 | the work, and the source code for shared libraries and dynamically
143 | linked subprograms that the work is specifically designed to require,
144 | such as by intimate data communication or control flow between those
145 | subprograms and other parts of the work.
146 | 
147 |   The Corresponding Source need not include anything that users
148 | can regenerate automatically from other parts of the Corresponding
149 | Source.
150 | 
151 |   The Corresponding Source for a work in source code form is that
152 | same work.
153 | 
154 |   2. Basic Permissions.
155 | 
156 |   All rights granted under this License are granted for the term of
157 | copyright on the Program, and are irrevocable provided the stated
158 | conditions are met.  This License explicitly affirms your unlimited
159 | permission to run the unmodified Program.  The output from running a
160 | covered work is covered by this License only if the output, given its
161 | content, constitutes a covered work.  This License acknowledges your
162 | rights of fair use or other equivalent, as provided by copyright law.
163 | 
164 |   You may make, run and propagate covered works that you do not
165 | convey, without conditions so long as your license otherwise remains
166 | in force.  You may convey covered works to others for the sole purpose
167 | of having them make modifications exclusively for you, or provide you
168 | with facilities for running those works, provided that you comply with
169 | the terms of this License in conveying all material for which you do
170 | not control copyright.  Those thus making or running the covered works
171 | for you must do so exclusively on your behalf, under your direction
172 | and control, on terms that prohibit them from making any copies of
173 | your copyrighted material outside their relationship with you.
174 | 
175 |   Conveying under any other circumstances is permitted solely under
176 | the conditions stated below.  Sublicensing is not allowed; section 10
177 | makes it unnecessary.
178 | 
179 |   3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180 | 
181 |   No covered work shall be deemed part of an effective technological
182 | measure under any applicable law fulfilling obligations under article
183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
184 | similar laws prohibiting or restricting circumvention of such
185 | measures.
186 | 
187 |   When you convey a covered work, you waive any legal power to forbid
188 | circumvention of technological measures to the extent such circumvention
189 | is effected by exercising rights under this License with respect to
190 | the covered work, and you disclaim any intention to limit operation or
191 | modification of the work as a means of enforcing, against the work's
192 | users, your or third parties' legal rights to forbid circumvention of
193 | technological measures.
194 | 
195 |   4. Conveying Verbatim Copies.
196 | 
197 |   You may convey verbatim copies of the Program's source code as you
198 | receive it, in any medium, provided that you conspicuously and
199 | appropriately publish on each copy an appropriate copyright notice;
200 | keep intact all notices stating that this License and any
201 | non-permissive terms added in accord with section 7 apply to the code;
202 | keep intact all notices of the absence of any warranty; and give all
203 | recipients a copy of this License along with the Program.
204 | 
205 |   You may charge any price or no price for each copy that you convey,
206 | and you may offer support or warranty protection for a fee.
207 | 
208 |   5. Conveying Modified Source Versions.
209 | 
210 |   You may convey a work based on the Program, or the modifications to
211 | produce it from the Program, in the form of source code under the
212 | terms of section 4, provided that you also meet all of these conditions:
213 | 
214 |     a) The work must carry prominent notices stating that you modified
215 |     it, and giving a relevant date.
216 | 
217 |     b) The work must carry prominent notices stating that it is
218 |     released under this License and any conditions added under section
219 |     7.  This requirement modifies the requirement in section 4 to
220 |     "keep intact all notices".
221 | 
222 |     c) You must license the entire work, as a whole, under this
223 |     License to anyone who comes into possession of a copy.  This
224 |     License will therefore apply, along with any applicable section 7
225 |     additional terms, to the whole of the work, and all its parts,
226 |     regardless of how they are packaged.  This License gives no
227 |     permission to license the work in any other way, but it does not
228 |     invalidate such permission if you have separately received it.
229 | 
230 |     d) If the work has interactive user interfaces, each must display
231 |     Appropriate Legal Notices; however, if the Program has interactive
232 |     interfaces that do not display Appropriate Legal Notices, your
233 |     work need not make them do so.
234 | 
235 |   A compilation of a covered work with other separate and independent
236 | works, which are not by their nature extensions of the covered work,
237 | and which are not combined with it such as to form a larger program,
238 | in or on a volume of a storage or distribution medium, is called an
239 | "aggregate" if the compilation and its resulting copyright are not
240 | used to limit the access or legal rights of the compilation's users
241 | beyond what the individual works permit.  Inclusion of a covered work
242 | in an aggregate does not cause this License to apply to the other
243 | parts of the aggregate.
244 | 
245 |   6. Conveying Non-Source Forms.
246 | 
247 |   You may convey a covered work in object code form under the terms
248 | of sections 4 and 5, provided that you also convey the
249 | machine-readable Corresponding Source under the terms of this License,
250 | in one of these ways:
251 | 
252 |     a) Convey the object code in, or embodied in, a physical product
253 |     (including a physical distribution medium), accompanied by the
254 |     Corresponding Source fixed on a durable physical medium
255 |     customarily used for software interchange.
256 | 
257 |     b) Convey the object code in, or embodied in, a physical product
258 |     (including a physical distribution medium), accompanied by a
259 |     written offer, valid for at least three years and valid for as
260 |     long as you offer spare parts or customer support for that product
261 |     model, to give anyone who possesses the object code either (1) a
262 |     copy of the Corresponding Source for all the software in the
263 |     product that is covered by this License, on a durable physical
264 |     medium customarily used for software interchange, for a price no
265 |     more than your reasonable cost of physically performing this
266 |     conveying of source, or (2) access to copy the
267 |     Corresponding Source from a network server at no charge.
268 | 
269 |     c) Convey individual copies of the object code with a copy of the
270 |     written offer to provide the Corresponding Source.  This
271 |     alternative is allowed only occasionally and noncommercially, and
272 |     only if you received the object code with such an offer, in accord
273 |     with subsection 6b.
274 | 
275 |     d) Convey the object code by offering access from a designated
276 |     place (gratis or for a charge), and offer equivalent access to the
277 |     Corresponding Source in the same way through the same place at no
278 |     further charge.  You need not require recipients to copy the
279 |     Corresponding Source along with the object code.  If the place to
280 |     copy the object code is a network server, the Corresponding Source
281 |     may be on a different server (operated by you or a third party)
282 |     that supports equivalent copying facilities, provided you maintain
283 |     clear directions next to the object code saying where to find the
284 |     Corresponding Source.  Regardless of what server hosts the
285 |     Corresponding Source, you remain obligated to ensure that it is
286 |     available for as long as needed to satisfy these requirements.
287 | 
288 |     e) Convey the object code using peer-to-peer transmission, provided
289 |     you inform other peers where the object code and Corresponding
290 |     Source of the work are being offered to the general public at no
291 |     charge under subsection 6d.
292 | 
293 |   A separable portion of the object code, whose source code is excluded
294 | from the Corresponding Source as a System Library, need not be
295 | included in conveying the object code work.
296 | 
297 |   A "User Product" is either (1) a "consumer product", which means any
298 | tangible personal property which is normally used for personal, family,
299 | or household purposes, or (2) anything designed or sold for incorporation
300 | into a dwelling.  In determining whether a product is a consumer product,
301 | doubtful cases shall be resolved in favor of coverage.  For a particular
302 | product received by a particular user, "normally used" refers to a
303 | typical or common use of that class of product, regardless of the status
304 | of the particular user or of the way in which the particular user
305 | actually uses, or expects or is expected to use, the product.  A product
306 | is a consumer product regardless of whether the product has substantial
307 | commercial, industrial or non-consumer uses, unless such uses represent
308 | the only significant mode of use of the product.
309 | 
310 |   "Installation Information" for a User Product means any methods,
311 | procedures, authorization keys, or other information required to install
312 | and execute modified versions of a covered work in that User Product from
313 | a modified version of its Corresponding Source.  The information must
314 | suffice to ensure that the continued functioning of the modified object
315 | code is in no case prevented or interfered with solely because
316 | modification has been made.
317 | 
318 |   If you convey an object code work under this section in, or with, or
319 | specifically for use in, a User Product, and the conveying occurs as
320 | part of a transaction in which the right of possession and use of the
321 | User Product is transferred to the recipient in perpetuity or for a
322 | fixed term (regardless of how the transaction is characterized), the
323 | Corresponding Source conveyed under this section must be accompanied
324 | by the Installation Information.  But this requirement does not apply
325 | if neither you nor any third party retains the ability to install
326 | modified object code on the User Product (for example, the work has
327 | been installed in ROM).
328 | 
329 |   The requirement to provide Installation Information does not include a
330 | requirement to continue to provide support service, warranty, or updates
331 | for a work that has been modified or installed by the recipient, or for
332 | the User Product in which it has been modified or installed.  Access to a
333 | network may be denied when the modification itself materially and
334 | adversely affects the operation of the network or violates the rules and
335 | protocols for communication across the network.
336 | 
337 |   Corresponding Source conveyed, and Installation Information provided,
338 | in accord with this section must be in a format that is publicly
339 | documented (and with an implementation available to the public in
340 | source code form), and must require no special password or key for
341 | unpacking, reading or copying.
342 | 
343 |   7. Additional Terms.
344 | 
345 |   "Additional permissions" are terms that supplement the terms of this
346 | License by making exceptions from one or more of its conditions.
347 | Additional permissions that are applicable to the entire Program shall
348 | be treated as though they were included in this License, to the extent
349 | that they are valid under applicable law.  If additional permissions
350 | apply only to part of the Program, that part may be used separately
351 | under those permissions, but the entire Program remains governed by
352 | this License without regard to the additional permissions.
353 | 
354 |   When you convey a copy of a covered work, you may at your option
355 | remove any additional permissions from that copy, or from any part of
356 | it.  (Additional permissions may be written to require their own
357 | removal in certain cases when you modify the work.)  You may place
358 | additional permissions on material, added by you to a covered work,
359 | for which you have or can give appropriate copyright permission.
360 | 
361 |   Notwithstanding any other provision of this License, for material you
362 | add to a covered work, you may (if authorized by the copyright holders of
363 | that material) supplement the terms of this License with terms:
364 | 
365 |     a) Disclaiming warranty or limiting liability differently from the
366 |     terms of sections 15 and 16 of this License; or
367 | 
368 |     b) Requiring preservation of specified reasonable legal notices or
369 |     author attributions in that material or in the Appropriate Legal
370 |     Notices displayed by works containing it; or
371 | 
372 |     c) Prohibiting misrepresentation of the origin of that material, or
373 |     requiring that modified versions of such material be marked in
374 |     reasonable ways as different from the original version; or
375 | 
376 |     d) Limiting the use for publicity purposes of names of licensors or
377 |     authors of the material; or
378 | 
379 |     e) Declining to grant rights under trademark law for use of some
380 |     trade names, trademarks, or service marks; or
381 | 
382 |     f) Requiring indemnification of licensors and authors of that
383 |     material by anyone who conveys the material (or modified versions of
384 |     it) with contractual assumptions of liability to the recipient, for
385 |     any liability that these contractual assumptions directly impose on
386 |     those licensors and authors.
387 | 
388 |   All other non-permissive additional terms are considered "further
389 | restrictions" within the meaning of section 10.  If the Program as you
390 | received it, or any part of it, contains a notice stating that it is
391 | governed by this License along with a term that is a further
392 | restriction, you may remove that term.  If a license document contains
393 | a further restriction but permits relicensing or conveying under this
394 | License, you may add to a covered work material governed by the terms
395 | of that license document, provided that the further restriction does
396 | not survive such relicensing or conveying.
397 | 
398 |   If you add terms to a covered work in accord with this section, you
399 | must place, in the relevant source files, a statement of the
400 | additional terms that apply to those files, or a notice indicating
401 | where to find the applicable terms.
402 | 
403 |   Additional terms, permissive or non-permissive, may be stated in the
404 | form of a separately written license, or stated as exceptions;
405 | the above requirements apply either way.
406 | 
407 |   8. Termination.
408 | 
409 |   You may not propagate or modify a covered work except as expressly
410 | provided under this License.  Any attempt otherwise to propagate or
411 | modify it is void, and will automatically terminate your rights under
412 | this License (including any patent licenses granted under the third
413 | paragraph of section 11).
414 | 
415 |   However, if you cease all violation of this License, then your
416 | license from a particular copyright holder is reinstated (a)
417 | provisionally, unless and until the copyright holder explicitly and
418 | finally terminates your license, and (b) permanently, if the copyright
419 | holder fails to notify you of the violation by some reasonable means
420 | prior to 60 days after the cessation.
421 | 
422 |   Moreover, your license from a particular copyright holder is
423 | reinstated permanently if the copyright holder notifies you of the
424 | violation by some reasonable means, this is the first time you have
425 | received notice of violation of this License (for any work) from that
426 | copyright holder, and you cure the violation prior to 30 days after
427 | your receipt of the notice.
428 | 
429 |   Termination of your rights under this section does not terminate the
430 | licenses of parties who have received copies or rights from you under
431 | this License.  If your rights have been terminated and not permanently
432 | reinstated, you do not qualify to receive new licenses for the same
433 | material under section 10.
434 | 
435 |   9. Acceptance Not Required for Having Copies.
436 | 
437 |   You are not required to accept this License in order to receive or
438 | run a copy of the Program.  Ancillary propagation of a covered work
439 | occurring solely as a consequence of using peer-to-peer transmission
440 | to receive a copy likewise does not require acceptance.  However,
441 | nothing other than this License grants you permission to propagate or
442 | modify any covered work.  These actions infringe copyright if you do
443 | not accept this License.  Therefore, by modifying or propagating a
444 | covered work, you indicate your acceptance of this License to do so.
445 | 
446 |   10. Automatic Licensing of Downstream Recipients.
447 | 
448 |   Each time you convey a covered work, the recipient automatically
449 | receives a license from the original licensors, to run, modify and
450 | propagate that work, subject to this License.  You are not responsible
451 | for enforcing compliance by third parties with this License.
452 | 
453 |   An "entity transaction" is a transaction transferring control of an
454 | organization, or substantially all assets of one, or subdividing an
455 | organization, or merging organizations.  If propagation of a covered
456 | work results from an entity transaction, each party to that
457 | transaction who receives a copy of the work also receives whatever
458 | licenses to the work the party's predecessor in interest had or could
459 | give under the previous paragraph, plus a right to possession of the
460 | Corresponding Source of the work from the predecessor in interest, if
461 | the predecessor has it or can get it with reasonable efforts.
462 | 
463 |   You may not impose any further restrictions on the exercise of the
464 | rights granted or affirmed under this License.  For example, you may
465 | not impose a license fee, royalty, or other charge for exercise of
466 | rights granted under this License, and you may not initiate litigation
467 | (including a cross-claim or counterclaim in a lawsuit) alleging that
468 | any patent claim is infringed by making, using, selling, offering for
469 | sale, or importing the Program or any portion of it.
470 | 
471 |   11. Patents.
472 | 
473 |   A "contributor" is a copyright holder who authorizes use under this
474 | License of the Program or a work on which the Program is based.  The
475 | work thus licensed is called the contributor's "contributor version".
476 | 
477 |   A contributor's "essential patent claims" are all patent claims
478 | owned or controlled by the contributor, whether already acquired or
479 | hereafter acquired, that would be infringed by some manner, permitted
480 | by this License, of making, using, or selling its contributor version,
481 | but do not include claims that would be infringed only as a
482 | consequence of further modification of the contributor version.  For
483 | purposes of this definition, "control" includes the right to grant
484 | patent sublicenses in a manner consistent with the requirements of
485 | this License.
486 | 
487 |   Each contributor grants you a non-exclusive, worldwide, royalty-free
488 | patent license under the contributor's essential patent claims, to
489 | make, use, sell, offer for sale, import and otherwise run, modify and
490 | propagate the contents of its contributor version.
491 | 
492 |   In the following three paragraphs, a "patent license" is any express
493 | agreement or commitment, however denominated, not to enforce a patent
494 | (such as an express permission to practice a patent or covenant not to
495 | sue for patent infringement).  To "grant" such a patent license to a
496 | party means to make such an agreement or commitment not to enforce a
497 | patent against the party.
498 | 
499 |   If you convey a covered work, knowingly relying on a patent license,
500 | and the Corresponding Source of the work is not available for anyone
501 | to copy, free of charge and under the terms of this License, through a
502 | publicly available network server or other readily accessible means,
503 | then you must either (1) cause the Corresponding Source to be so
504 | available, or (2) arrange to deprive yourself of the benefit of the
505 | patent license for this particular work, or (3) arrange, in a manner
506 | consistent with the requirements of this License, to extend the patent
507 | license to downstream recipients.  "Knowingly relying" means you have
508 | actual knowledge that, but for the patent license, your conveying the
509 | covered work in a country, or your recipient's use of the covered work
510 | in a country, would infringe one or more identifiable patents in that
511 | country that you have reason to believe are valid.
512 | 
513 |   If, pursuant to or in connection with a single transaction or
514 | arrangement, you convey, or propagate by procuring conveyance of, a
515 | covered work, and grant a patent license to some of the parties
516 | receiving the covered work authorizing them to use, propagate, modify
517 | or convey a specific copy of the covered work, then the patent license
518 | you grant is automatically extended to all recipients of the covered
519 | work and works based on it.
520 | 
521 |   A patent license is "discriminatory" if it does not include within
522 | the scope of its coverage, prohibits the exercise of, or is
523 | conditioned on the non-exercise of one or more of the rights that are
524 | specifically granted under this License.  You may not convey a covered
525 | work if you are a party to an arrangement with a third party that is
526 | in the business of distributing software, under which you make payment
527 | to the third party based on the extent of your activity of conveying
528 | the work, and under which the third party grants, to any of the
529 | parties who would receive the covered work from you, a discriminatory
530 | patent license (a) in connection with copies of the covered work
531 | conveyed by you (or copies made from those copies), or (b) primarily
532 | for and in connection with specific products or compilations that
533 | contain the covered work, unless you entered into that arrangement,
534 | or that patent license was granted, prior to 28 March 2007.
535 | 
536 |   Nothing in this License shall be construed as excluding or limiting
537 | any implied license or other defenses to infringement that may
538 | otherwise be available to you under applicable patent law.
539 | 
540 |   12. No Surrender of Others' Freedom.
541 | 
542 |   If conditions are imposed on you (whether by court order, agreement or
543 | otherwise) that contradict the conditions of this License, they do not
544 | excuse you from the conditions of this License.  If you cannot convey a
545 | covered work so as to satisfy simultaneously your obligations under this
546 | License and any other pertinent obligations, then as a consequence you may
547 | not convey it at all.  For example, if you agree to terms that obligate you
548 | to collect a royalty for further conveying from those to whom you convey
549 | the Program, the only way you could satisfy both those terms and this
550 | License would be to refrain entirely from conveying the Program.
551 | 
552 |   13. Use with the GNU Affero General Public License.
553 | 
554 |   Notwithstanding any other provision of this License, you have
555 | permission to link or combine any covered work with a work licensed
556 | under version 3 of the GNU Affero General Public License into a single
557 | combined work, and to convey the resulting work.  The terms of this
558 | License will continue to apply to the part which is the covered work,
559 | but the special requirements of the GNU Affero General Public License,
560 | section 13, concerning interaction through a network will apply to the
561 | combination as such.
562 | 
563 |   14. Revised Versions of this License.
564 | 
565 |   The Free Software Foundation may publish revised and/or new versions of
566 | the GNU General Public License from time to time.  Such new versions will
567 | be similar in spirit to the present version, but may differ in detail to
568 | address new problems or concerns.
569 | 
570 |   Each version is given a distinguishing version number.  If the
571 | Program specifies that a certain numbered version of the GNU General
572 | Public License "or any later version" applies to it, you have the
573 | option of following the terms and conditions either of that numbered
574 | version or of any later version published by the Free Software
575 | Foundation.  If the Program does not specify a version number of the
576 | GNU General Public License, you may choose any version ever published
577 | by the Free Software Foundation.
578 | 
579 |   If the Program specifies that a proxy can decide which future
580 | versions of the GNU General Public License can be used, that proxy's
581 | public statement of acceptance of a version permanently authorizes you
582 | to choose that version for the Program.
583 | 
584 |   Later license versions may give you additional or different
585 | permissions.  However, no additional obligations are imposed on any
586 | author or copyright holder as a result of your choosing to follow a
587 | later version.
588 | 
589 |   15. Disclaimer of Warranty.
590 | 
591 |   THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592 | APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596 | PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597 | IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599 | 
600 |   16. Limitation of Liability.
601 | 
602 |   IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610 | SUCH DAMAGES.
611 | 
612 |   17. Interpretation of Sections 15 and 16.
613 | 
614 |   If the disclaimer of warranty and limitation of liability provided
615 | above cannot be given local legal effect according to their terms,
616 | reviewing courts shall apply local law that most closely approximates
617 | an absolute waiver of all civil liability in connection with the
618 | Program, unless a warranty or assumption of liability accompanies a
619 | copy of the Program in return for a fee.
620 | 
621 |                      END OF TERMS AND CONDITIONS
622 | 
623 |             How to Apply These Terms to Your New Programs
624 | 
625 |   If you develop a new program, and you want it to be of the greatest
626 | possible use to the public, the best way to achieve this is to make it
627 | free software which everyone can redistribute and change under these terms.
628 | 
629 |   To do so, attach the following notices to the program.  It is safest
630 | to attach them to the start of each source file to most effectively
631 | state the exclusion of warranty; and each file should have at least
632 | the "copyright" line and a pointer to where the full notice is found.
633 | 
634 |     <one line to give the program's name and a brief idea of what it does.>
635 |     Copyright (C) <year>  <name of author>
636 | 
637 |     This program is free software: you can redistribute it and/or modify
638 |     it under the terms of the GNU General Public License as published by
639 |     the Free Software Foundation, either version 3 of the License, or
640 |     (at your option) any later version.
641 | 
642 |     This program is distributed in the hope that it will be useful,
643 |     but WITHOUT ANY WARRANTY; without even the implied warranty of
644 |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
645 |     GNU General Public License for more details.
646 | 
647 |     You should have received a copy of the GNU General Public License
648 |     along with this program.  If not, see <https://www.gnu.org/licenses/>.
649 | 
650 | Also add information on how to contact you by electronic and paper mail.
651 | 
652 |   If the program does terminal interaction, make it output a short
653 | notice like this when it starts in an interactive mode:
654 | 
655 |     <program>  Copyright (C) <year>  <name of author>
656 |     This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 |     This is free software, and you are welcome to redistribute it
658 |     under certain conditions; type `show c' for details.
659 | 
660 | The hypothetical commands `show w' and `show c' should show the appropriate
661 | parts of the General Public License.  Of course, your program's commands
662 | might be different; for a GUI interface, you would use an "about box".
663 | 
664 |   You should also get your employer (if you work as a programmer) or school,
665 | if any, to sign a "copyright disclaimer" for the program, if necessary.
666 | For more information on this, and how to apply and follow the GNU GPL, see
667 | <https://www.gnu.org/licenses/>.
668 | 
669 |   The GNU General Public License does not permit incorporating your program
670 | into proprietary programs.  If your program is a subroutine library, you
671 | may consider it more useful to permit linking proprietary applications with
672 | the library.  If this is what you want to do, use the GNU Lesser General
673 | Public License instead of this License.  But first, please read
674 | <https://www.gnu.org/licenses/why-not-lgpl.html>.
675 | 


--------------------------------------------------------------------------------
/README.en.md:
--------------------------------------------------------------------------------
  1 | <!-- markdownlint-disable MD028 MD033 MD045 -->
  2 | 
  3 | # reinstall
  4 | 
  5 | [![Codacy](https://img.shields.io/codacy/grade/dc679a17751448628fe6d8ac35e26eed?logo=Codacy&label=Codacy&style=flat-square)](https://app.codacy.com/gh/bin456789/reinstall/dashboard)
  6 | [![CodeFactor](https://img.shields.io/codefactor/grade/github/bin456789/reinstall?logo=CodeFactor&logoColor=white&label=CodeFactor&style=flat-square)](https://www.codefactor.io/repository/github/bin456789/reinstall)
  7 | [![Lines of Code](https://tokei.rs/b1/github/bin456789/reinstall?category=code&label=Lines%20of%20Code&style=flat-square)](https://github.com/XAMPPRocky/tokei_rs)
  8 | [![Telegram Group](https://img.shields.io/badge/Telegram-2CA5E0?style=flat-square&logo=telegram&logoColor=white)](https://t.me/reinstall_os)
  9 | [![Github Sponsors](https://img.shields.io/badge/sponsor-30363D?style=flat-square&logo=GitHub-Sponsors&logoColor=#EA4AAA)](https://github.com/sponsors/bin456789)
 10 | 
 11 | One-Click Script to Reinstall System [中文](README.md)
 12 | 
 13 | [![Sponsors](https://raw.githubusercontent.com/bin456789/sponsors/refs/heads/master/sponsors.svg)](https://github.com/sponsors/bin456789)
 14 | 
 15 | ## Highlights
 16 | 
 17 | - One-click Linux installation: Supports 19 common distributions.
 18 | - One-click Windows installation: Uses the official ISO for installation instead of custom images. The script can automatically retrieves the ISO link and installs common drivers like `Virtio`.
 19 | - Supports installation in any direction, i.e., `Linux to Linux`, `Linux to Windows`, `Windows to Windows`, `Windows to Linux`
 20 | - No need to input IP parameters; automatically recognizes dynamic and static IPs, supports `/32`, `/128`, `gateway outside subnet`, `IPv6 only`, `dual NIC`
 21 | - Specially optimized for low-spec servers, requires less memory than the official netboot
 22 | - Uses partition table ID to identify hard drives throughout the process, ensuring no wrong disk is written
 23 | - Supports BIOS and EFI boot, and ARM Server
 24 | - No homemades image included, all resources are obtained in real-time from mirror sites
 25 | 
 26 | ## System Requirements
 27 | 
 28 | The original system can be any system listed in the table.
 29 | 
 30 | The system requirements for the target system are as follows:
 31 | 
 32 | | System                                                                                                                                                                                                                                                                                                                                                                 | Version                               | Memory    | Disk             |
 33 | | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | --------- | ---------------- |
 34 | | <img width="16" height="16" src="https://www.alpinelinux.org/alpine-logo.ico" /> Alpine                                                                                                                                                                                                                                                                                | 3.19, 3.20, 3.21, 3.22                | 256 MB    | 1 GB             |
 35 | | <img width="16" height="16" src="https://www.debian.org/favicon.ico" /> Debian                                                                                                                                                                                                                                                                                         | 9, 10, 11, 12                         | 256 MB    | 1 ~ 1.5 GB ^     |
 36 | | <img width="16" height="16" src="https://github.com/bin456789/reinstall/assets/7548515/f74b3d5b-085f-4df3-bcc9-8a9bd80bb16d" /> Kali                                                                                                                                                                                                                                   | Rolling                               | 256 MB    | 1 ~ 1.5 GB ^     |
 37 | | <img width="16" height="16" src="https://documentation.ubuntu.com/server/_static/favicon.png" /> Ubuntu                                                                                                                                                                                                                                                                | 16.04 LTS - 24.04 LTS, 25.04          | 512 MB \* | 2 GB             |
 38 | | <img width="16" height="16" src="https://img.alicdn.com/imgextra/i1/O1CN01oJnJZg1yK4RzI4Rx2_!!6000000006559-2-tps-118-118.png" /> Anolis                                                                                                                                                                                                                               | 7, 8, 23                              | 512 MB \* | 5 GB             |
 39 | | <img width="16" height="16" src="https://www.redhat.com/favicon.ico" /> RHEL &nbsp;<img width="16" height="16" src="https://almalinux.org/fav/favicon.ico" /> AlmaLinux &nbsp;<img width="16" height="16" src="https://rockylinux.org/favicon.png" /> Rocky &nbsp;<img width="16" height="16" src="https://www.oracle.com/asset/web/favicons/favicon-32.png" /> Oracle | 8, 9, 10 (if released)                | 512 MB \* | 5 GB             |
 40 | | <img width="16" height="16" src="https://opencloudos.org/qq.ico" /> OpenCloudOS                                                                                                                                                                                                                                                                                        | 8, 9, Stream 23                       | 512 MB \* | 5 GB             |
 41 | | <img width="16" height="16" src="https://www.centos.org/assets/icons/favicon.svg" /> CentOS Stream                                                                                                                                                                                                                                                                     | 9, 10                                 | 512 MB \* | 5 GB             |
 42 | | <img width="16" height="16" src="https://fedoraproject.org/favicon.ico" /> Fedora                                                                                                                                                                                                                                                                                      | 41, 42                                | 512 MB \* | 5 GB             |
 43 | | <img width="16" height="16" src="https://www.openeuler.org/favicon.ico" /> openEuler                                                                                                                                                                                                                                                                                   | 20.03 LTS - 24.03 LTS, 25.03          | 512 MB \* | 5 GB             |
 44 | | <img width="16" height="16" src="https://static.opensuse.org/favicon.ico" /> openSUSE                                                                                                                                                                                                                                                                                  | Leap 15.6, Tumbleweed (Rolling)       | 512 MB \* | 5 GB             |
 45 | | <img width="16" height="16" src="https://nixos.org/favicon.svg" /> NixOS                                                                                                                                                                                                                                                                                               | 25.05                                 | 512 MB    | 5 GB             |
 46 | | <img width="16" height="16" src="https://archlinux.org/static/favicon.png" /> Arch                                                                                                                                                                                                                                                                                     | Rolling                               | 512 MB    | 5 GB             |
 47 | | <img width="16" height="16" src="https://www.gentoo.org/assets/img/logo/gentoo-g.png" /> Gentoo                                                                                                                                                                                                                                                                        | Rolling                               | 512 MB    | 5 GB             |
 48 | | <img width="16" height="16" src="https://aosc.io/assets/distros/aosc-os.svg" /> AOSC OS                                                                                                                                                                                                                                                                                | Rolling                               | 512 MB    | 5 GB             |
 49 | | <img width="16" height="16" src="https://www.fnnas.com/favicon.ico" /> fnOS                                                                                                                                                                                                                                                                                            | Beta                                  | 512 MB    | 8 GB             |
 50 | | <img width="16" height="16" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows (DD)                                                                                                                                                                                                              | Any                                   | 512 MB    | Depends on image |
 51 | | <img width="16" height="16" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows (ISO)                                                                                                                                                                                                             | Vista, 7, 8.x (Server 2008 - 2012 R2) | 512 MB    | 25 GB            |
 52 | | <img width="16" height="16" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows (ISO)                                                                                                                                                                                                             | 10, 11 (Server 2016 - 2025)           | 1 GB      | 25 GB            |
 53 | 
 54 | \* Indicates installation using cloud images, not traditional network installation.
 55 | 
 56 | ^ Indicates requiring either 256 MB memory + 1.5 GB disk, or 512 MB memory + 1 GB disk
 57 | 
 58 | > [!WARNING]
 59 | > ❌ This script does not support OpenVZ or LXC virtual machines.
 60 | >
 61 | > Please use <https://github.com/LloydAsp/OsMutation> instead.
 62 | 
 63 | ## Download (Current system is <img width="20" height="20" src="https://www.kernel.org/theme/images/logos/favicon.png" /> Linux)
 64 | 
 65 | For server outside China:
 66 | 
 67 | ```bash
 68 | curl -O https://raw.githubusercontent.com/bin456789/reinstall/main/reinstall.sh || wget -O reinstall.sh $_
 69 | ```
 70 | 
 71 | For server inside China:
 72 | 
 73 | ```bash
 74 | curl -O https://cnb.cool/bin456789/reinstall/-/git/raw/main/reinstall.sh || wget -O reinstall.sh $_
 75 | ```
 76 | 
 77 | ## Download (Current system is <img width="20" height="20" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows)
 78 | 
 79 | > [!IMPORTANT]
 80 | > Before proceeding, please disable the 'Real-time protection' feature in `Windows Defender`. This feature may prevent `certutil` from downloading any files.
 81 | 
 82 | <details>
 83 | 
 84 | <summary>Resolving Script Download Issues on Windows 7</summary>
 85 | 
 86 | Due to lack of support for TLS 1.2, SHA-256, or outdated root certificates, Windows Vista, 7, and Server 2008 (R2) may not be able to download scripts automatically. Manual downloading is required, as follows:
 87 | 
 88 | Use Internet Explorer (enable TLS 1.2 in IE's advanced settings first) to download, or use Remote Desktop to save the following two files into the same directory:
 89 | 
 90 | - <https://raw.githubusercontent.com/bin456789/reinstall/main/reinstall.bat>
 91 | 
 92 | - <https://www.cygwin.com/setup-x86.exe>
 93 | 
 94 | To use, run the downloaded `reinstall.bat`.
 95 | 
 96 | </details>
 97 | 
 98 | For server outside China:
 99 | 
100 | ```batch
101 | certutil -urlcache -f -split https://raw.githubusercontent.com/bin456789/reinstall/main/reinstall.bat
102 | ```
103 | 
104 | For server inside China:
105 | 
106 | ```batch
107 | certutil -urlcache -f -split https://cnb.cool/bin456789/reinstall/-/git/raw/main/reinstall.bat
108 | ```
109 | 
110 | ## Usage
111 | 
112 | **All features** can be used on both Linux and Windows.
113 | 
114 | - on Linux, run `bash reinstall.sh ...`
115 | - on Windows, first run `cmd`, then run `.\reinstall.bat ...`
116 |   - If the link in the parameter contains special characters, it should be enclosed in `""`, not `''`.
117 | 
118 | ### Feature 1: Install <img width="16" height="16" src="https://www.kernel.org/theme/images/logos/favicon.png" /> Linux
119 | 
120 | - The username is `root` with a default password of `123@@@`.
121 | - When installing the latest version, the version number does not need to be specified.
122 | - Maximizes disk space usage: no boot partition (except for Fedora) and no swap partition.
123 | - Automatically selects different optimized kernels based on machine type, such as `Cloud` or `HWE` kernels.
124 | - When installing Red Hat, you must provide the `qcow2` image link obtained from <https://access.redhat.com/downloads/content/rhel>. You can also install other RHEL-based OS, such as `Alibaba Cloud Linux` and `TencentOS Server`.
125 | - After reinstallation, if you need to change the SSH port or switch to key-based login, make sure to also modify the files inside `/etc/ssh/sshd_config.d/`.
126 | 
127 | ```bash
128 | bash reinstall.sh anolis      7|8|23
129 |                   rocky       8|9|10
130 |                   oracle      8|9
131 |                   almalinux   8|9|10
132 |                   opencloudos 8|9|23
133 |                   centos      9|10
134 |                   fedora      41|42
135 |                   nixos       25.05
136 |                   debian      9|10|11|12
137 |                   opensuse    15.6|tumbleweed
138 |                   alpine      3.19|3.20|3.21|3.22
139 |                   openeuler   20.03|22.03|24.03|25.03
140 |                   ubuntu      16.04|18.04|20.04|22.04|24.04|25.04 [--minimal]
141 |                   kali
142 |                   arch
143 |                   gentoo
144 |                   aosc
145 |                   fnos
146 |                   redhat      --img="http://access.cdn.redhat.com/xxx.qcow2"
147 | ```
148 | 
149 | #### Optional Parameters
150 | 
151 | - `--password PASSWORD` Set the password
152 | - `--ssh-key KEY` Set up SSH login public key, supports these formats. When using public key, password is empty.
153 |   - `--ssh-key "ssh-rsa ..."`
154 |   - `--ssh-key "ssh-ed25519 ..."`
155 |   - `--ssh-key "ecdsa-sha2-nistp256/384/521 ..."`
156 |   - `--ssh-key http://path/to/public_key`
157 |   - `--ssh-key github:your_username`
158 |   - `--ssh-key gitlab:your_username`
159 |   - `--ssh-key /path/to/public_key`
160 |   - `--ssh-key C:\path\to\public_key`
161 | - `--ssh-port PORT` Change the SSH port (for log observation during installation and for the new system)
162 | - `--web-port PORT` Change the Web port (for log observation during installation)
163 | - `--frpc-toml /path/to/frpc.toml` Add frpc for intranet tunneling
164 | - `--hold 2` Prevent reboot after installation completes, allowing SSH login to modify system content; the system is mounted at `/os` (this feature is not supported on Debian/Kali).
165 | 
166 | > [!TIP]
167 | > When installing Debian/Kali, x86 architectures can monitor the installation progress through VNC from server provider, while ARM architectures can use the serial console.
168 | >
169 | > When installing other systems, can monitor the progress through various methods (SSH, HTTP 80 port, VNC from server provider, serial console).
170 | > <br />Even if errors occur during the installation process, you can still install to Alpine via SSH by running `/trans.sh alpine`
171 | 
172 | <details>
173 | 
174 | <summary>Experimental Features</summary>
175 | 
176 | Install Debian using a cloud image
177 | 
178 | - Suitable for machines with slower CPUs
179 | 
180 | ```bash
181 | bash reinstall.sh debian --ci
182 | ```
183 | 
184 | Install CentOS, AlmaLinux, Rocky, Fedora using ISO
185 | 
186 | - Only supports machines with more than 2G of memory and dynamic IP.
187 | - Password is `123@@@`, and the SSH port is `22`; modifying them using parameters is not supported.
188 | 
189 | ```bash
190 | bash reinstall.sh centos --installer
191 | ```
192 | 
193 | Install Ubuntu using ISO
194 | 
195 | - Only supports machines with more than 1G of memory and dynamic IP.
196 | - Password is `123@@@`, and the SSH port is `22`; modifying them using parameters is not supported.
197 | 
198 | ```bash
199 | bash reinstall.sh ubuntu --installer
200 | ```
201 | 
202 | </details>
203 | 
204 | ### Feature 2: DD
205 | 
206 | - Supports `raw` and `vhd` image formats (either uncompressed or compressed as `.gz`, `.xz`, `.zst`, `.tar`, `.tar.gz`, `.tar.xz`, `.tar.zst`).
207 | - When deploy a Windows image, the system disk will be automatically expanded, and machines with a static IP will have their IP configured, and may take a few minutes after the first boot for the configuration to take effect.
208 | - When deploy a Linux image, will **NOT** modify any contents of the image.
209 | 
210 | ```bash
211 | bash reinstall.sh dd --img "https://example.com/xxx.xz"
212 | ```
213 | 
214 | #### Optional Parameters
215 | 
216 | - `--allow-ping` Configure Windows Firewall to Allow Ping Responses (DD Windows only)
217 | - `--rdp-port PORT` Change RDP port (DD Windows only)
218 | - `--ssh-port PORT` Change SSH port (for log observation during installation)
219 | - `--web-port PORT` Change Web port (for log observation during installation)
220 | - `--frpc-toml /path/to/frpc.toml` Add frpc for intranet tunneling (DD Windows only)
221 | - `--hold 2` Prevent reboot after the DD process finishes, allowing SSH login to modify system content. The Windows system will be mounted at `/os`, but Linux systems will **NOT** be automatically mounted.
222 | 
223 | > [!TIP]
224 | > Can monitor the progress through various methods (SSH, HTTP 80 port, VNC from server provider, serial console).
225 | > <br />Even if errors occur during the installation process, you can still install to Alpine via SSH by running `/trans.sh alpine`
226 | 
227 | ### Feature 3: Reboot to <img width="16" height="16" src="https://www.alpinelinux.org/alpine-logo.ico" /> Alpine Live OS (RAM OS)
228 | 
229 | - You can use SSH to backup/restore disk, manually perform DD operations, modify partitions, and manually install Alpine, Arch, Gentoo, and other systems.
230 | - Username `root`, Default password `123@@@`
231 | - If manual operations do not damage the original system, rebooting will return to the original system.
232 | 
233 | ```bash
234 | bash reinstall.sh alpine --hold=1
235 | ```
236 | 
237 | #### Optional Parameters
238 | 
239 | - `--password PASSWORD` Set password
240 | - `--ssh-port PORT` Change SSH port
241 | - `--ssh-key KEY` Set up SSH login public key, supports these formats. When using public key, password is empty.
242 |   - `--ssh-key "ssh-rsa ..."`
243 |   - `--ssh-key "ssh-ed25519 ..."`
244 |   - `--ssh-key "ecdsa-sha2-nistp256/384/521 ..."`
245 |   - `--ssh-key http://path/to/public_key`
246 |   - `--ssh-key github:your_username`
247 |   - `--ssh-key gitlab:your_username`
248 |   - `--ssh-key /path/to/public_key`
249 |   - `--ssh-key C:\path\to\public_key`
250 | - `--frpc-toml /path/to/frpc.toml` Add frpc for intranet tunneling
251 | 
252 | ### Feature 4: Reboot to <img width="16" height="16" src="https://netboot.xyz/img/favicon.ico" /> netboot.xyz
253 | 
254 | - Can manually install [more systems](https://github.com/netbootxyz/netboot.xyz?tab=readme-ov-file#what-operating-systems-are-currently-available-on-netbootxyz) using vendor backend VNC.
255 | - If manual operations do not damage the original system, rebooting will return to the original system.
256 | 
257 | ```bash
258 | bash reinstall.sh netboot.xyz
259 | ```
260 | 
261 | ![netboot.xyz](https://netboot.xyz/images/netboot.xyz.gif)
262 | 
263 | ### Feature 5: Install <img width="16" height="16" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows ISO
264 | 
265 | ![Windows Installation](https://github.com/bin456789/reinstall/assets/7548515/07c1aea2-1ce3-4967-904f-aaf9d6eec3f7)
266 | 
267 | - Username `administrator`, Default password `123@@@`
268 | - If remote login fails, try using the username `.\administrator`.
269 | - The machine with a static IP will automatically configure the IP. It may take a few minutes to take effect on the first boot.
270 | - Supports all languages.
271 | 
272 | #### Supported Systems
273 | 
274 | - Windows (Vista ~ 11)
275 | - Windows Server (2008 ~ 2025)
276 |   - Windows Server Essentials \*
277 |   - Windows Server (Semi) Annual Channel \*
278 |   - Hyper-V Server \*
279 |   - Azure Stack HCI \*
280 | 
281 | #### Method 1: Let the Script Automatically Search for ISO
282 | 
283 | - The script will search for ISOs from <https://massgrave.dev/genuine-installation-media>, a site that collects official ISOs.
284 | - Systems marked with \* do not support automatic ISO searching.
285 | 
286 | ```bash
287 | bash reinstall.sh windows \
288 |      --image-name "Windows 11 Enterprise LTSC 2024" \
289 |      --lang zh-cn
290 | ```
291 | 
292 | <details>
293 | <summary>Supported languages</summary>
294 | 
295 | ```text
296 | ar-sa
297 | bg-bg
298 | cs-cz
299 | da-dk
300 | de-de
301 | el-gr
302 | en-gb
303 | en-us
304 | es-es
305 | es-mx
306 | et-ee
307 | fi-fi
308 | fr-ca
309 | fr-fr
310 | he-il
311 | hr-hr
312 | hu-hu
313 | it-it
314 | ja-jp
315 | ko-kr
316 | lt-lt
317 | lv-lv
318 | nb-no
319 | nl-nl
320 | pl-pl
321 | pt-pt
322 | pt-br
323 | ro-ro
324 | ru-ru
325 | sk-sk
326 | sl-si
327 | sr-latn-rs
328 | sv-se
329 | th-th
330 | tr-tr
331 | uk-ua
332 | zh-cn
333 | zh-hk
334 | zh-tw
335 | ```
336 | 
337 | </details>
338 | 
339 | #### Method 2: Specify the ISO link manually
340 | 
341 | - If you don't know the `--image-name`, you can enter any value. After rebooting, connect via SSH and re-enter the correct value based on the error messages.
342 | 
343 | ```bash
344 | bash reinstall.sh windows \
345 |      --image-name "Windows 11 Enterprise LTSC 2024 Evaluation" \
346 |      --iso "https://go.microsoft.com/fwlink/?linkid=2289029"
347 | ```
348 | 
349 | or Magnet Link
350 | 
351 | ```bash
352 | bash reinstall.sh windows \
353 |      --image-name "Windows 11 Enterprise LTSC 2024" \
354 |      --iso "magnet:?xt=urn:btih:7352bd2db48c3381dffa783763dc75aa4a6f1cff"
355 | ```
356 | 
357 | <details>
358 | 
359 | <summary>The following website provides ISO links.</summary>
360 | 
361 | - General
362 |   - <https://msdl.gravesoft.dev>
363 |   - <https://massgrave.dev/genuine-installation-media>
364 |   - <https://next.itellyou.cn>
365 |   - <https://www.xitongku.com>
366 |   - <https://www.microsoft.com/software-download/windows10> (Need to open it with a non-Windows User-Agent)
367 |   - <https://www.microsoft.com/software-download/windows11>
368 |   - <https://www.microsoft.com/software-download/windows11arm64>
369 | - Evaluation
370 |   - <https://www.microsoft.com/evalcenter/download-windows-10-enterprise>
371 |   - <https://www.microsoft.com/evalcenter/download-windows-11-enterprise>
372 |   - <https://www.microsoft.com/evalcenter/download-windows-11-iot-enterprise-ltsc-eval>
373 |   - <https://www.microsoft.com/evalcenter/download-windows-server-2012-r2>
374 |   - <https://www.microsoft.com/evalcenter/download-windows-server-2016>
375 |   - <https://www.microsoft.com/evalcenter/download-windows-server-2019>
376 |   - <https://www.microsoft.com/evalcenter/download-windows-server-2022>
377 |   - <https://www.microsoft.com/evalcenter/download-windows-server-2025>
378 | - Insider Preview
379 |   - <https://www.microsoft.com/en-us/software-download/windowsinsiderpreviewiso>
380 |   - <https://www.microsoft.com/en-us/software-download/windowsinsiderpreviewserver>
381 | 
382 | </details>
383 | 
384 | #### Optional Parameters
385 | 
386 | - `--password PASSWORD` Set Password
387 | - `--allow-ping` Configure Windows Firewall to Allow Ping Responses
388 | - `--rdp-port PORT` Change RDP port
389 | - `--ssh-port PORT` Change SSH port (for log observation during installation)
390 | - `--web-port PORT` Change Web port (for log observation during installation)
391 | - `--add-driver INF_OR_DIR` Add additional driver, specifying .inf path, or the folder contains .inf file.
392 |   - The driver must be downloaded locally first.
393 |   - This parameter can be set multiple times to add different driver.
394 | - `--frpc-toml /path/to/frpc.toml` Add frpc for intranet tunneling
395 | - `--hold 2` Allow SSH connections for modifying the disk content before rebooting into the official Windows installation program, with the disk mounted at `/os`.
396 | 
397 | #### The following drivers will automatic download and install as needed, without the need for manual addition
398 | 
399 | - Virtio ([Virtio][virtio-virtio], [Alibaba Cloud][virtio-aliyun], [Tencent Cloud][virtio-qcloud], [GCP][virtio-gcp])
400 | - XEN ([~~XEN~~][xen-xen] (unsigned), [Citrix][xen-citrix], [AWS][xen-aws])
401 | - AWS ([ENA Network Adapter][aws-ena], [NVME Storage Controller][aws-nvme])
402 | - GCP ([gVNIC Network Adapter][gcp-gvnic], [GGA Display Adapter][gcp-gga])
403 | - Azure ([MANA Network Adapter][azure-mana])
404 | - Intel ([VMD Storage Controller][intel-vmd], Network Adapter: [7][intel-nic-7], [8][intel-nic-8], [8.1][intel-nic-8.1], [10][intel-nic-10], [11][intel-nic-11], [2008 R2][intel-nic-2008-r2], [2012][intel-nic-2012], [2012 R2][intel-nic-2012-r2], [2016][intel-nic-2016], [2019][intel-nic-2019], [2022][intel-nic-2022], [2025][intel-nic-2025])
405 | 
406 | [virtio-virtio]: https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/
407 | [virtio-aliyun]: https://www.alibabacloud.com/help/ecs/user-guide/install-the-virtio-driver-1
408 | [virtio-qcloud]: https://cloud.tencent.com/document/product/213/17815#b84b2032-752c-43c4-a509-73530b8f82ff
409 | [virtio-gcp]: https://console.cloud.google.com/storage/browser/gce-windows-drivers-public
410 | [xen-xen]: https://xenproject.org/resources/downloads/
411 | [xen-aws]: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/xen-drivers-overview.html
412 | [xen-citrix]: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Upgrading_PV_drivers.html#win2008-citrix-upgrade
413 | [aws-ena]: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ena-driver-releases-windows.html
414 | [aws-nvme]: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/nvme-driver-version-history.html
415 | [gcp-gvnic]: https://cloud.google.com/compute/docs/networking/using-gvnic
416 | [gcp-gga]: https://cloud.google.com/compute/docs/instances/enable-instance-virtual-display
417 | [azure-mana]: https://learn.microsoft.com/azure/virtual-network/accelerated-networking-mana-windows
418 | [intel-vmd]: https://www.intel.com/content/www/us/en/download/849936/intel-rapid-storage-technology-driver-installation-software-with-intel-optane-memory-12th-to-15th-gen-platforms.html
419 | [intel-nic-7]: https://www.intel.com/content/www/us/en/download/15590/intel-network-adapter-driver-for-windows-7-final-release.html
420 | [intel-nic-8]: https://www.intel.com/content/www/us/en/download/16765/intel-network-adapter-driver-for-windows-8-final-release.html
421 | [intel-nic-8.1]: https://www.intel.com/content/www/us/en/download/17479/intel-network-adapter-driver-for-windows-8-1.html
422 | [intel-nic-10]: https://www.intel.com/content/www/us/en/download/18293/intel-network-adapter-driver-for-windows-10.html
423 | [intel-nic-11]: https://www.intel.com/content/www/us/en/download/727998/intel-network-adapter-driver-for-microsoft-windows-11.html
424 | [intel-nic-2008-r2]: https://www.intel.com/content/www/us/en/download/15591/intel-network-adapter-driver-for-windows-server-2008-r2-final-release.html
425 | [intel-nic-2012]: https://www.intel.com/content/www/us/en/download/16789/intel-network-adapter-driver-for-windows-server-2012.html
426 | [intel-nic-2012-r2]: https://www.intel.com/content/www/us/en/download/17480/intel-network-adapter-driver-for-windows-server-2012-r2.html
427 | [intel-nic-2016]: https://www.intel.com/content/www/us/en/download/18737/intel-network-adapter-driver-for-windows-server-2016.html
428 | [intel-nic-2019]: https://www.intel.com/content/www/us/en/download/19372/intel-network-adapter-driver-for-windows-server-2019.html
429 | [intel-nic-2022]: https://www.intel.com/content/www/us/en/download/706171/intel-network-adapter-driver-for-windows-server-2022.html
430 | [intel-nic-2025]: https://www.intel.com/content/www/us/en/download/838943/intel-network-adapter-driver-for-windows-server-2025.html
431 | 
432 | #### How to Specify the Image Name `--image-name`
433 | 
434 | Typically, an ISO will contain multiple system versions, such as Home Edition and Professional Edition. The image name `--image-name` is used to specify the version to be installed, and it is case-insensitive when entered.
435 | 
436 | You can use tools like DISM, DISM++, or Wimlib to query the image names included in the ISO.
437 | 
438 | Commonly used image names include:
439 | 
440 | ```text
441 | Windows 7 Ultimate
442 | Windows 11 Pro
443 | Windows 11 Enterprise LTSC 2024
444 | Windows Server 2025 SERVERDATACENTER
445 | ```
446 | 
447 | #### How to Use [DISM++](https://github.com/Chuyu-Team/Dism-Multi-language/releases) to Query the Image Names Included in the ISO
448 | 
449 | Open File menu > Open Image File, select the iso to be installed to get the image name (full system name), and all available image names are installable.
450 | 
451 | ![image-name](https://github.com/bin456789/reinstall/assets/7548515/5aae0a9b-61e2-4f66-bb98-d470a6beaac2)
452 | 
453 | > [!WARNING]
454 | > Vista (Server 2008) and 32-bit systems may lack drivers.
455 | 
456 | > [!WARNING]
457 | > For EFI machines without CSM enabled, Windows 7 (Server 2008 R2) cannot be installed.
458 | >
459 | > Hyper-V (Azure) requires selecting the appropriate VM generation: <https://learn.microsoft.com/windows-server/virtualization/hyper-v/plan/should-i-create-a-generation-1-or-2-virtual-machine-in-hyper-v>
460 | 
461 | > [!WARNING]
462 | > In the Chinese version of Windows 10 LTSC 2021 ISO `zh-cn_windows_10_enterprise_ltsc_2021_x64_dvd_033b7312.iso`, the `wsappx` process may indefinitely consume CPU resources.
463 | >
464 | > The solution is to update the system patches or manually install the `VCLibs` library <https://www.google.com/search?q=ltsc+wsappx>.
465 | 
466 | #### Considerations for Installing Windows on ARM
467 | 
468 | Most ARM machines support installing latest Windows 11.
469 | 
470 | During the installation process, you might encounter a black screen, and the serial console may display `ConvertPages: failed to find range`, but neither issue affects the installation.
471 | 
472 | | Compatibility | Cloud Provider | Instance Type | Issues                                                                                                                                                 |
473 | | ------------- | -------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
474 | | ✔️            | Azure          | B2pts_v2      |                                                                                                                                                        |
475 | | ✔️            | Alibaba Cloud  | g6r, c6r      |                                                                                                                                                        |
476 | | ✔️            | Alibaba Cloud  | g8y, c8y, r8y | There is a chance of hanging at the boot logo during restart; forced reboot will resolve it.                                                           |
477 | | ✔️            | AWS            | T4g           |                                                                                                                                                        |
478 | | ✔️            | Scaleway       | COPARM1       |                                                                                                                                                        |
479 | | ✔️            | Gcore          |               |                                                                                                                                                        |
480 | | ❔            | Oracle Cloud   | A1.Flex       | Installation success is not guaranteed; newer instances are more likely to succeed.<br />Manual loading of GPU drivers is required after installation. |
481 | | ❌            | Google Cloud   | t2a           | Missing network card drivers                                                                                                                           |
482 | 
483 | <details>
484 | 
485 | <summary>Loading Graphics Driver on Oracle Cloud</summary>
486 | 
487 | Log in to the server using Remote Desktop, open Device Manager, locate the graphics card, select "Update Driver," and choose `Red Hat VirtIO GPU DOD controller` from the list. There's no need to download the drivers in advance.
488 | 
489 | ![virtio-gpu-1](https://github.com/user-attachments/assets/503e1d82-4fa9-4486-917e-73326ad7c988)
490 | ![virtio-gpu-2](https://github.com/user-attachments/assets/bf3a9af6-13d8-4f93-9d6c-d3b2dbddb37d)
491 | ![virtio-gpu-3](https://github.com/user-attachments/assets/a9006a78-838f-45bf-a556-2dba193d3c03)
492 | 
493 | </details>
494 | 
495 | ## Discussion
496 | 
497 | [![GitHub Issues](https://img.shields.io/badge/github-%23121011.svg?style=for-the-badge&logo=github&logoColor=white)](https://github.com/bin456789/reinstall/issues)
498 | [![Telegram Group](https://img.shields.io/badge/Telegram-2CA5E0?style=for-the-badge&logo=telegram&logoColor=white)](https://t.me/reinstall_os)
499 | 
500 | ## How to Modify the Script for Your Own
501 | 
502 | 1. Fork this repository.
503 | 2. Modify the `confhome` and `confhome_cn` at the beginning of `reinstall.sh` and `reinstall.bat`.
504 | 3. Make changes to the other code.
505 | 
506 | ## Thanks
507 | 
508 | [![Github Sponsors](https://img.shields.io/badge/sponsor-30363D?style=for-the-badge&logo=GitHub-Sponsors&logoColor=#EA4AAA)](https://github.com/sponsors/bin456789)
509 | 
510 | Thanks to the following businesses for providing free servers.
511 | 
512 | [![Oracle Cloud](https://github.com/bin456789/reinstall/assets/7548515/8b430ed4-8344-4f96-b4da-c2bda031cc90)](https://www.oracle.com/cloud/)
513 | [![DartNode](https://github.com/bin456789/reinstall/assets/7548515/435d6740-bcdd-4f3a-a196-2f60ae397f17)](https://dartnode.com/)
514 | 


--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
  1 | <!-- markdownlint-disable MD028 MD033 MD045 -->
  2 | 
  3 | # reinstall
  4 | 
  5 | [![Codacy](https://img.shields.io/codacy/grade/dc679a17751448628fe6d8ac35e26eed?logo=Codacy&label=Codacy&style=flat-square)](https://app.codacy.com/gh/bin456789/reinstall/dashboard)
  6 | [![CodeFactor](https://img.shields.io/codefactor/grade/github/bin456789/reinstall?logo=CodeFactor&logoColor=white&label=CodeFactor&style=flat-square)](https://www.codefactor.io/repository/github/bin456789/reinstall)
  7 | [![Lines of Code](https://tokei.rs/b1/github/bin456789/reinstall?category=code&label=Lines%20of%20Code&style=flat-square)](https://github.com/XAMPPRocky/tokei_rs)
  8 | [![Telegram Group](https://img.shields.io/badge/Telegram-2CA5E0?style=flat-square&logo=telegram&logoColor=white)](https://t.me/reinstall_os)
  9 | [![Github Sponsors](https://img.shields.io/badge/sponsor-30363D?style=flat-square&logo=GitHub-Sponsors&logoColor=#EA4AAA)](https://github.com/sponsors/bin456789)
 10 | 
 11 | 一键重装脚本 [English](README.en.md)
 12 | 
 13 | [![Sponsors](https://raw.githubusercontent.com/bin456789/sponsors/refs/heads/master/sponsors.svg)](https://github.com/sponsors/bin456789)
 14 | 
 15 | ## 亮点
 16 | 
 17 | - 一键安装 Linux,支持 19 种常见发行版
 18 | - 一键安装 Windows,使用官方 ISO 安装而非自制镜像,脚本会自动获取 ISO 链接、自动安装 Virtio 等常见驱动
 19 | - 支持任意方向重装,即 `Linux to Linux`、`Linux to Windows`、`Windows to Windows`、`Windows to Linux`
 20 | - 无需填写 IP 参数,自动识别动静态,支持 `/32`、`/128`、`网关不在子网范围内`、`纯 IPv6`、`双网卡`
 21 | - 专门适配低配小鸡,比官方 netboot 需要更少的内存
 22 | - 全程用分区表 ID 识别硬盘,确保不会写错硬盘
 23 | - 支持 BIOS、EFI 引导,支持 ARM 服务器
 24 | - 不含自制包,所有资源均实时从镜像源获得
 25 | 
 26 | ## 系统要求
 27 | 
 28 | 原系统可以是表格中的任意系统
 29 | 
 30 | 目标系统的配置要求如下:
 31 | 
 32 | | 系统                                                                                                                                                                                                                                                                                                                                                                   | 版本                                  | 内存      | 硬盘         |
 33 | | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | --------- | ------------ |
 34 | | <img width="16" height="16" src="https://www.alpinelinux.org/alpine-logo.ico" /> Alpine                                                                                                                                                                                                                                                                                | 3.19, 3.20, 3.21, 3.22                | 256 MB    | 1 GB         |
 35 | | <img width="16" height="16" src="https://www.debian.org/favicon.ico" /> Debian                                                                                                                                                                                                                                                                                         | 9, 10, 11, 12                         | 256 MB    | 1 ~ 1.5 GB ^ |
 36 | | <img width="16" height="16" src="https://github.com/bin456789/reinstall/assets/7548515/f74b3d5b-085f-4df3-bcc9-8a9bd80bb16d" /> Kali                                                                                                                                                                                                                                   | 滚动                                  | 256 MB    | 1 ~ 1.5 GB ^ |
 37 | | <img width="16" height="16" src="https://documentation.ubuntu.com/server/_static/favicon.png" /> Ubuntu                                                                                                                                                                                                                                                                | 16.04 LTS - 24.04 LTS, 25.04          | 512 MB \* | 2 GB         |
 38 | | <img width="16" height="16" src="https://img.alicdn.com/imgextra/i1/O1CN01oJnJZg1yK4RzI4Rx2_!!6000000006559-2-tps-118-118.png" /> Anolis                                                                                                                                                                                                                               | 7, 8, 23                              | 512 MB \* | 5 GB         |
 39 | | <img width="16" height="16" src="https://www.redhat.com/favicon.ico" /> RHEL &nbsp;<img width="16" height="16" src="https://almalinux.org/fav/favicon.ico" /> AlmaLinux &nbsp;<img width="16" height="16" src="https://rockylinux.org/favicon.png" /> Rocky &nbsp;<img width="16" height="16" src="https://www.oracle.com/asset/web/favicons/favicon-32.png" /> Oracle | 8, 9, 10 (如果有)                     | 512 MB \* | 5 GB         |
 40 | | <img width="16" height="16" src="https://opencloudos.org/qq.ico" /> OpenCloudOS                                                                                                                                                                                                                                                                                        | 8, 9, Stream 23                       | 512 MB \* | 5 GB         |
 41 | | <img width="16" height="16" src="https://www.centos.org/assets/icons/favicon.svg" /> CentOS Stream                                                                                                                                                                                                                                                                     | 9, 10                                 | 512 MB \* | 5 GB         |
 42 | | <img width="16" height="16" src="https://fedoraproject.org/favicon.ico" /> Fedora                                                                                                                                                                                                                                                                                      | 41, 42                                | 512 MB \* | 5 GB         |
 43 | | <img width="16" height="16" src="https://www.openeuler.org/favicon.ico" /> openEuler                                                                                                                                                                                                                                                                                   | 20.03 LTS - 24.03 LTS, 25.03          | 512 MB \* | 5 GB         |
 44 | | <img width="16" height="16" src="https://static.opensuse.org/favicon.ico" /> openSUSE                                                                                                                                                                                                                                                                                  | Leap 15.6, Tumbleweed (滚动)          | 512 MB \* | 5 GB         |
 45 | | <img width="16" height="16" src="https://nixos.org/favicon.svg" /> NixOS                                                                                                                                                                                                                                                                                               | 25.05                                 | 512 MB    | 5 GB         |
 46 | | <img width="16" height="16" src="https://archlinux.org/static/favicon.png" /> Arch                                                                                                                                                                                                                                                                                     | 滚动                                  | 512 MB    | 5 GB         |
 47 | | <img width="16" height="16" src="https://www.gentoo.org/assets/img/logo/gentoo-g.png" /> Gentoo                                                                                                                                                                                                                                                                        | 滚动                                  | 512 MB    | 5 GB         |
 48 | | <img width="16" height="16" src="https://aosc.io/assets/distros/aosc-os.svg" /> 安同 OS                                                                                                                                                                                                                                                                                | 滚动                                  | 512 MB    | 5 GB         |
 49 | | <img width="16" height="16" src="https://www.fnnas.com/favicon.ico" /> 飞牛 fnOS                                                                                                                                                                                                                                                                                       | 公测                                  | 512 MB    | 8 GB         |
 50 | | <img width="16" height="16" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows (DD)                                                                                                                                                                                                              | 任何                                  | 512 MB    | 取决于镜像   |
 51 | | <img width="16" height="16" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows (ISO)                                                                                                                                                                                                             | Vista, 7, 8.x (Server 2008 - 2012 R2) | 512 MB    | 25 GB        |
 52 | | <img width="16" height="16" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows (ISO)                                                                                                                                                                                                             | 10, 11 (Server 2016 - 2025)           | 1 GB      | 25 GB        |
 53 | 
 54 | \* 表示使用云镜像安装,非传统网络安装
 55 | 
 56 | ^ 表示需要 256 MB 内存 + 1.5 GB 硬盘,或 512 MB 内存 + 1 GB 硬盘
 57 | 
 58 | > [!WARNING]
 59 | > ❌ 本脚本不支持 OpenVZ、LXC 虚拟机
 60 | >
 61 | > 请改用 <https://github.com/LloydAsp/OsMutation>
 62 | 
 63 | ## 下载(当前系统是 <img width="20" height="20" src="https://www.kernel.org/theme/images/logos/favicon.png" /> Linux)
 64 | 
 65 | 国外服务器:
 66 | 
 67 | ```bash
 68 | curl -O https://raw.githubusercontent.com/bin456789/reinstall/main/reinstall.sh || wget -O reinstall.sh $_
 69 | ```
 70 | 
 71 | 国内服务器:
 72 | 
 73 | ```bash
 74 | curl -O https://cnb.cool/bin456789/reinstall/-/git/raw/main/reinstall.sh || wget -O reinstall.sh $_
 75 | ```
 76 | 
 77 | ## 下载(当前系统是 <img width="20" height="20" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows)
 78 | 
 79 | > [!IMPORTANT]
 80 | > 请先关闭 `Windows Defender` 的 `实时保护` 功能。该功能会阻止 `certutil` 下载任何文件。
 81 | 
 82 | <details>
 83 | 
 84 | <summary>解决 Windows 7 下无法下载脚本</summary>
 85 | 
 86 | 由于不支持 TLS 1.2、SHA-256、根证书没有更新等原因,Vista,7 和 Server 2008 (R2) 可能无法自动下载脚本,因此需要手动下载,具体操作如下:
 87 | 
 88 | 用 IE 下载 (先在 IE 高级设置里启用 TLS 1.2),或者通过远程桌面,将这两个文件保存到同一个目录
 89 | 
 90 | - <https://raw.githubusercontent.com/bin456789/reinstall/main/reinstall.bat>
 91 | 
 92 | - <https://www.cygwin.com/setup-x86.exe>
 93 | 
 94 | 使用时运行下载的 `reinstall.bat`
 95 | 
 96 | </details>
 97 | 
 98 | 国外服务器:
 99 | 
100 | ```batch
101 | certutil -urlcache -f -split https://raw.githubusercontent.com/bin456789/reinstall/main/reinstall.bat
102 | ```
103 | 
104 | 国内服务器:
105 | 
106 | ```batch
107 | certutil -urlcache -f -split https://cnb.cool/bin456789/reinstall/-/git/raw/main/reinstall.bat
108 | ```
109 | 
110 | ## 使用
111 | 
112 | **所有功能** 都可在 Linux / Windows 下运行
113 | 
114 | - Linux 下运行 `bash reinstall.sh ...`
115 | - Windows 下先运行 `cmd`,再运行 `reinstall.bat ...`
116 |   - 如果参数中的链接包含特殊字符,要用 `""` 将链接包起来,不能用 `''`
117 | 
118 | ### 功能 1: 安装 <img width="16" height="16" src="https://www.kernel.org/theme/images/logos/favicon.png" /> Linux
119 | 
120 | - 用户名 `root` 默认密码 `123@@@`
121 | - 安装最新版可不输入版本号
122 | - 最大化利用磁盘空间:不含 boot 分区(Fedora 例外),不含 swap 分区
123 | - 自动根据机器类型选择不同的优化内核,例如 `Cloud`、`HWE` 内核
124 | - 安装 Red Hat 时需填写 <https://access.redhat.com/downloads/content/rhel> 得到的 `qcow2` 镜像链接,也可以安装其它类 RHEL 系统,例如 `Alibaba Cloud Linux` 和 `TencentOS Server`
125 | - 重装后如需修改 SSH 端口或者改成密钥登录,注意还要修改 `/etc/ssh/sshd_config.d/` 里面的文件
126 | 
127 | ```bash
128 | bash reinstall.sh anolis      7|8|23
129 |                   rocky       8|9|10
130 |                   oracle      8|9
131 |                   almalinux   8|9|10
132 |                   opencloudos 8|9|23
133 |                   centos      9|10
134 |                   fedora      41|42
135 |                   nixos       25.05
136 |                   debian      9|10|11|12
137 |                   opensuse    15.6|tumbleweed
138 |                   alpine      3.19|3.20|3.21|3.22
139 |                   openeuler   20.03|22.03|24.03|25.03
140 |                   ubuntu      16.04|18.04|20.04|22.04|24.04|25.04 [--minimal]
141 |                   kali
142 |                   arch
143 |                   gentoo
144 |                   aosc
145 |                   fnos
146 |                   redhat      --img="http://access.cdn.redhat.com/xxx.qcow2"
147 | ```
148 | 
149 | #### 可选参数
150 | 
151 | - `--password PASSWORD` 设置密码
152 | - `--ssh-key KEY` 设置 SSH 登录公钥,支持以下格式。当使用公钥时,密码为空
153 |   - `--ssh-key "ssh-rsa ..."`
154 |   - `--ssh-key "ssh-ed25519 ..."`
155 |   - `--ssh-key "ecdsa-sha2-nistp256/384/521 ..."`
156 |   - `--ssh-key http://path/to/public_key`
157 |   - `--ssh-key github:your_username`
158 |   - `--ssh-key gitlab:your_username`
159 |   - `--ssh-key /path/to/public_key`
160 |   - `--ssh-key C:\path\to\public_key`
161 | - `--ssh-port PORT` 修改 SSH 端口(安装期间观察日志用,也作用于新系统)
162 | - `--web-port PORT` 修改 Web 端口(安装期间观察日志用)
163 | - `--frpc-toml /path/to/frpc.toml` 添加 frpc 内网穿透
164 | - `--hold 2` 安装结束后不重启,此时可以 SSH 登录修改系统内容,系统挂载在 `/os` (此功能不支持 Debian/Kali)
165 | 
166 | > [!TIP]
167 | > 安装 Debian/Kali 时,x86 可通过商家后台 VNC 查看安装进度,ARM 可通过串行控制台查看安装进度。
168 | >
169 | > 安装其它系统时,可通过多种方式(SSH、HTTP 80 端口、商家后台 VNC、串行控制台)查看安装进度。
170 | > <br />即使安装过程出错,也能通过 SSH 运行 `/trans.sh alpine` 安装到 Alpine。
171 | 
172 | <details>
173 | 
174 | <summary>实验性功能</summary>
175 | 
176 | 云镜像安装 Debian
177 | 
178 | - 适合于 CPU 较慢的机器
179 | 
180 | ```bash
181 | bash reinstall.sh debian --ci
182 | ```
183 | 
184 | ISO 安装 CentOS, AlmaLinux, Rocky, Fedora
185 | 
186 | - 仅支持内存大于 2G 且为动态 IP 的机器
187 | - 密码 `123@@@`,SSH 端口 `22`,不支持用参数修改
188 | 
189 | ```bash
190 | bash reinstall.sh centos --installer
191 | ```
192 | 
193 | ISO 安装 Ubuntu
194 | 
195 | - 仅支持内存大于 1G 且为动态 IP 的机器
196 | - 密码 `123@@@`,SSH 端口 `22`,不支持用参数修改
197 | 
198 | ```bash
199 | bash reinstall.sh ubuntu --installer
200 | ```
201 | 
202 | </details>
203 | 
204 | ### 功能 2: DD
205 | 
206 | - 支持 `raw` `vhd` 格式的镜像(未压缩,或者压缩成 `.gz` `.xz` `.zst` `.tar` `.tar.gz` `.tar.xz` `.tar.zst`)
207 | - DD Windows 镜像时,会自动扩展系统盘,静态 IP 的机器会配置好 IP,可能首次开机几分钟后才生效
208 | - DD Linux 镜像时,**不会**修改镜像的任何内容
209 | 
210 | ```bash
211 | bash reinstall.sh dd --img "https://example.com/xxx.xz"
212 | ```
213 | 
214 | #### 可选参数
215 | 
216 | - `--allow-ping` 设置 Windows 防火墙允许被 Ping (仅限 DD Windows)
217 | - `--rdp-port PORT` 修改 RDP 端口 (仅限 DD Windows)
218 | - `--ssh-port PORT` 修改 SSH 端口(安装期间观察日志用)
219 | - `--web-port PORT` 修改 Web 端口(安装期间观察日志用)
220 | - `--frpc-toml /path/to/frpc.toml` 添加 frpc 内网穿透(仅限 DD Windows)
221 | - `--hold 2` DD 结束后不重启,此时可以 SSH 登录修改系统内容,Windows 系统会挂载在 `/os`,Linux 系统**不会**自动挂载
222 | 
223 | > [!TIP]
224 | > 可通过多种方式(SSH、HTTP 80 端口、商家后台 VNC、串行控制台)查看安装进度。
225 | > <br />即使安装过程出错,也能通过 SSH 运行 `/trans.sh alpine` 安装到 Alpine。
226 | 
227 | ### 功能 3: 重启到 <img width="16" height="16" src="https://www.alpinelinux.org/alpine-logo.ico" /> Alpine Live OS(内存系统)
228 | 
229 | - 可用 ssh 连接,进行备份/恢复硬盘、手动 DD、修改分区、手动安装 Alpine/Arch/Gentoo 等操作
230 | - 用户名 `root` 默认密码 `123@@@`
231 | - 如果手动操作没有破坏原系统,再次重启将回到原系统
232 | 
233 | ```bash
234 | bash reinstall.sh alpine --hold=1
235 | ```
236 | 
237 | #### 可选参数
238 | 
239 | - `--password PASSWORD` 设置密码
240 | - `--ssh-port PORT` 修改 SSH 端口
241 | - `--ssh-key KEY` 设置 SSH 登录公钥,支持以下格式。当使用公钥时,密码为空
242 |   - `--ssh-key "ssh-rsa ..."`
243 |   - `--ssh-key "ssh-ed25519 ..."`
244 |   - `--ssh-key "ecdsa-sha2-nistp256/384/521 ..."`
245 |   - `--ssh-key http://path/to/public_key`
246 |   - `--ssh-key github:your_username`
247 |   - `--ssh-key gitlab:your_username`
248 |   - `--ssh-key /path/to/public_key`
249 |   - `--ssh-key C:\path\to\public_key`
250 | - `--frpc-toml /path/to/frpc.toml` 添加 frpc 内网穿透
251 | 
252 | ### 功能 4: 重启到 <img width="16" height="16" src="https://netboot.xyz/img/favicon.ico" /> netboot.xyz
253 | 
254 | - 可使用商家后台 VNC 手动安装 [更多系统](https://github.com/netbootxyz/netboot.xyz?tab=readme-ov-file#what-operating-systems-are-currently-available-on-netbootxyz)
255 | - 如果手动操作没有破坏原系统,再次重启将回到原系统
256 | 
257 | ```bash
258 | bash reinstall.sh netboot.xyz
259 | ```
260 | 
261 | ![netboot.xyz](https://netboot.xyz/images/netboot.xyz.gif)
262 | 
263 | ### 功能 5: 安装 <img width="16" height="16" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows ISO
264 | 
265 | ![Windows 安装界面](https://github.com/bin456789/reinstall/assets/7548515/07c1aea2-1ce3-4967-904f-aaf9d6eec3f7)
266 | 
267 | - 用户名 `administrator` 默认密码 `123@@@`
268 | - 如果远程登录失败,可以尝试使用用户名 `.\administrator`
269 | - 静态机器会自动配置好 IP,可能首次开机几分钟后才生效
270 | - 支持所有语言
271 | 
272 | #### 支持的系统
273 | 
274 | - Windows (Vista ~ 11)
275 | - Windows Server (2008 ~ 2025)
276 |   - Windows Server Essentials \*
277 |   - Windows Server (Semi) Annual Channel \*
278 |   - Hyper-V Server \*
279 |   - Azure Stack HCI \*
280 | 
281 | #### 方法 1: 让脚本自动查找 ISO
282 | 
283 | - 脚本会从 <https://massgrave.dev/genuine-installation-media> 查找 ISO,该网站专门提供官方 ISO 下载
284 | - 上面带 \* 的系统不支持自动查找 ISO
285 | 
286 | ```bash
287 | bash reinstall.sh windows \
288 |      --image-name "Windows 11 Enterprise LTSC 2024" \
289 |      --lang zh-cn
290 | ```
291 | 
292 | <details>
293 | <summary>支持的语言</summary>
294 | 
295 | ```text
296 | ar-sa
297 | bg-bg
298 | cs-cz
299 | da-dk
300 | de-de
301 | el-gr
302 | en-gb
303 | en-us
304 | es-es
305 | es-mx
306 | et-ee
307 | fi-fi
308 | fr-ca
309 | fr-fr
310 | he-il
311 | hr-hr
312 | hu-hu
313 | it-it
314 | ja-jp
315 | ko-kr
316 | lt-lt
317 | lv-lv
318 | nb-no
319 | nl-nl
320 | pl-pl
321 | pt-pt
322 | pt-br
323 | ro-ro
324 | ru-ru
325 | sk-sk
326 | sl-si
327 | sr-latn-rs
328 | sv-se
329 | th-th
330 | tr-tr
331 | uk-ua
332 | zh-cn
333 | zh-hk
334 | zh-tw
335 | ```
336 | 
337 | </details>
338 | 
339 | #### 方法 2: 自行指定 ISO 连接
340 | 
341 | - 如果不知道 `--image-name`,可以随便填,在重启后连接 SSH,根据错误提示重新输入正确的值
342 | 
343 | ```bash
344 | bash reinstall.sh windows \
345 |      --image-name "Windows 11 Enterprise LTSC 2024 Evaluation" \
346 |      --iso "https://go.microsoft.com/fwlink/?linkid=2289029"
347 | ```
348 | 
349 | 或者磁力链接
350 | 
351 | ```bash
352 | bash reinstall.sh windows \
353 |      --image-name "Windows 11 Enterprise LTSC 2024" \
354 |      --iso "magnet:?xt=urn:btih:7352bd2db48c3381dffa783763dc75aa4a6f1cff"
355 | ```
356 | 
357 | <details>
358 | 
359 | <summary>以下网站可找到 ISO 链接</summary>
360 | 
361 | - 正式版
362 |   - <https://msdl.gravesoft.dev>
363 |   - <https://massgrave.dev/genuine-installation-media>
364 |   - <https://next.itellyou.cn>
365 |   - <https://www.xitongku.com>
366 |   - <https://www.microsoft.com/software-download/windows10> (需用非 Windows User-Agent 打开)
367 |   - <https://www.microsoft.com/software-download/windows11>
368 |   - <https://www.microsoft.com/software-download/windows11arm64>
369 | - 评估版
370 |   - <https://www.microsoft.com/evalcenter/download-windows-10-enterprise>
371 |   - <https://www.microsoft.com/evalcenter/download-windows-11-enterprise>
372 |   - <https://www.microsoft.com/evalcenter/download-windows-11-iot-enterprise-ltsc-eval>
373 |   - <https://www.microsoft.com/evalcenter/download-windows-server-2012-r2>
374 |   - <https://www.microsoft.com/evalcenter/download-windows-server-2016>
375 |   - <https://www.microsoft.com/evalcenter/download-windows-server-2019>
376 |   - <https://www.microsoft.com/evalcenter/download-windows-server-2022>
377 |   - <https://www.microsoft.com/evalcenter/download-windows-server-2025>
378 | - Insider 预览版
379 |   - <https://www.microsoft.com/en-us/software-download/windowsinsiderpreviewiso>
380 |   - <https://www.microsoft.com/en-us/software-download/windowsinsiderpreviewserver>
381 | 
382 | </details>
383 | 
384 | #### 可选参数
385 | 
386 | - `--password PASSWORD` 设置密码
387 | - `--allow-ping` 设置 Windows 防火墙允许被 Ping
388 | - `--rdp-port PORT` 更改 RDP 端口
389 | - `--ssh-port PORT` 修改 SSH 端口(安装期间观察日志用)
390 | - `--web-port PORT` 修改 Web 端口(安装期间观察日志用)
391 | - `--add-driver INF_OR_DIR` 添加额外驱动,填写 .inf 路径,或者 .inf 所在的文件夹
392 |   - 需先下载驱动到本地
393 |   - 可多次设置该参数以添加不同的驱动
394 | - `--frpc-toml /path/to/frpc.toml` 添加 frpc 内网穿透
395 | - `--hold 2` 在进入 Windows 官方安装程序之前,可以 SSH 登录修改硬盘内容,硬盘挂载在 `/os`
396 | 
397 | #### 以下驱动会自动按需下载安装,无需手动添加
398 | 
399 | - Virtio ([Virtio][virtio-virtio], [阿里云][virtio-aliyun], [腾讯云][virtio-qcloud], [GCP][virtio-gcp])
400 | - XEN ([~~XEN~~][xen-xen] (未签名), [Citrix][xen-citrix], [AWS][xen-aws])
401 | - AWS ([ENA 网卡][aws-ena], [NVME 存储控制器][aws-nvme])
402 | - GCP ([gVNIC 网卡][gcp-gvnic], [GGA 显卡][gcp-gga])
403 | - Azure ([MANA 网卡][azure-mana])
404 | - Intel ([VMD 存储控制器][intel-vmd], 网卡: [7][intel-nic-7], [8][intel-nic-8], [8.1][intel-nic-8.1], [10][intel-nic-10], [11][intel-nic-11], [2008 R2][intel-nic-2008-r2], [2012][intel-nic-2012], [2012 R2][intel-nic-2012-r2], [2016][intel-nic-2016], [2019][intel-nic-2019], [2022][intel-nic-2022], [2025][intel-nic-2025])
405 | 
406 | [virtio-virtio]: https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/
407 | [virtio-aliyun]: https://www.alibabacloud.com/help/ecs/user-guide/install-the-virtio-driver-1
408 | [virtio-qcloud]: https://cloud.tencent.com/document/product/213/17815#b84b2032-752c-43c4-a509-73530b8f82ff
409 | [virtio-gcp]: https://console.cloud.google.com/storage/browser/gce-windows-drivers-public
410 | [xen-xen]: https://xenproject.org/resources/downloads/
411 | [xen-aws]: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/xen-drivers-overview.html
412 | [xen-citrix]: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Upgrading_PV_drivers.html#win2008-citrix-upgrade
413 | [aws-ena]: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ena-driver-releases-windows.html
414 | [aws-nvme]: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/nvme-driver-version-history.html
415 | [gcp-gvnic]: https://cloud.google.com/compute/docs/networking/using-gvnic
416 | [gcp-gga]: https://cloud.google.com/compute/docs/instances/enable-instance-virtual-display
417 | [azure-mana]: https://learn.microsoft.com/azure/virtual-network/accelerated-networking-mana-windows
418 | [intel-vmd]: https://www.intel.com/content/www/us/en/download/849936/intel-rapid-storage-technology-driver-installation-software-with-intel-optane-memory-12th-to-15th-gen-platforms.html
419 | [intel-nic-7]: https://www.intel.com/content/www/us/en/download/15590/intel-network-adapter-driver-for-windows-7-final-release.html
420 | [intel-nic-8]: https://www.intel.com/content/www/us/en/download/16765/intel-network-adapter-driver-for-windows-8-final-release.html
421 | [intel-nic-8.1]: https://www.intel.com/content/www/us/en/download/17479/intel-network-adapter-driver-for-windows-8-1.html
422 | [intel-nic-10]: https://www.intel.com/content/www/us/en/download/18293/intel-network-adapter-driver-for-windows-10.html
423 | [intel-nic-11]: https://www.intel.com/content/www/us/en/download/727998/intel-network-adapter-driver-for-microsoft-windows-11.html
424 | [intel-nic-2008-r2]: https://www.intel.com/content/www/us/en/download/15591/intel-network-adapter-driver-for-windows-server-2008-r2-final-release.html
425 | [intel-nic-2012]: https://www.intel.com/content/www/us/en/download/16789/intel-network-adapter-driver-for-windows-server-2012.html
426 | [intel-nic-2012-r2]: https://www.intel.com/content/www/us/en/download/17480/intel-network-adapter-driver-for-windows-server-2012-r2.html
427 | [intel-nic-2016]: https://www.intel.com/content/www/us/en/download/18737/intel-network-adapter-driver-for-windows-server-2016.html
428 | [intel-nic-2019]: https://www.intel.com/content/www/us/en/download/19372/intel-network-adapter-driver-for-windows-server-2019.html
429 | [intel-nic-2022]: https://www.intel.com/content/www/us/en/download/706171/intel-network-adapter-driver-for-windows-server-2022.html
430 | [intel-nic-2025]: https://www.intel.com/content/www/us/en/download/838943/intel-network-adapter-driver-for-windows-server-2025.html
431 | 
432 | #### 如何填写映像名称 `--image-name`
433 | 
434 | 通常一个 ISO 会包含多个系统版本,例如家庭版、专业版。映像名称 `--image-name` 就是用来指定要安装的版本,填写时不区分大小写
435 | 
436 | 可以用 DISM、DISM++、Wimlib 等工具查询 ISO 包含的映像名称
437 | 
438 | 常用的映像名称有:
439 | 
440 | ```text
441 | Windows 7 Ultimate
442 | Windows 11 Pro
443 | Windows 11 Enterprise LTSC 2024
444 | Windows Server 2025 SERVERDATACENTER
445 | ```
446 | 
447 | #### 如何用 [DISM++](https://github.com/Chuyu-Team/Dism-Multi-language/releases) 查询 ISO 包含的映像名称
448 | 
449 | 打开文件菜单 > 打开映像文件,选择要安装的 iso,即可得到映像名称,所有映像名称都可以安装
450 | 
451 | ![image-name](https://github.com/bin456789/reinstall/assets/7548515/5aae0a9b-61e2-4f66-bb98-d470a6beaac2)
452 | 
453 | > [!WARNING]
454 | > Vista (Server 2008) 和 32 位系统可能会缺少驱动
455 | 
456 | > [!WARNING]
457 | > 未开启 CSM 的 EFI 机器,无法安装 Windows 7 (Server 2008 R2)
458 | >
459 | > Hyper-V (Azure) 需选择合适的虚拟机代系 <https://learn.microsoft.com/windows-server/virtualization/hyper-v/plan/should-i-create-a-generation-1-or-2-virtual-machine-in-hyper-v>
460 | 
461 | > [!WARNING]
462 | > Windows 10 LTSC 2021 中文版镜像 `zh-cn_windows_10_enterprise_ltsc_2021_x64_dvd_033b7312.iso` 的 `wsappx` 进程会长期占用 CPU
463 | >
464 | > 解决方法是更新系统补丁,或者手动安装 `VCLibs` 库 <https://www.google.com/search?q=ltsc+wsappx>
465 | 
466 | #### ARM 安装 Windows 的注意事项
467 | 
468 | 大部分 ARM 机器都支持安装最新版 Windows 11
469 | 
470 | 安装过程可能会黑屏,串行控制台可能会显示 `ConvertPages: failed to find range`,均不影响正常安装
471 | 
472 | | 兼容性 | 云服务商 | 实例类型      | 问题                                                                         |
473 | | ------ | -------- | ------------- | ---------------------------------------------------------------------------- |
474 | | ✔️     | Azure    | B2pts_v2      |                                                                              |
475 | | ✔️     | 阿里云   | g6r, c6r      |                                                                              |
476 | | ✔️     | 阿里云   | g8y, c8y, r8y | 有几率重启时卡开机 Logo,强制重启即可                                        |
477 | | ✔️     | AWS      | T4g           |                                                                              |
478 | | ✔️     | Scaleway | COPARM1       |                                                                              |
479 | | ✔️     | Gcore    |               |                                                                              |
480 | | ❔     | 甲骨文云 | A1.Flex       | 不一定能安装成功,越新创建的实例越容易成功<br />安装后还需要手动加载显卡驱动 |
481 | | ❌     | 谷歌云   | t2a           | 缺少网卡驱动                                                                 |
482 | 
483 | <details>
484 | 
485 | <summary>甲骨文云加载显卡驱动</summary>
486 | 
487 | 使用远程桌面登录到服务器,打开设备管理器,找到显卡,选择更新驱动,在列表中选择 `Red Hat VirtIO GPU DOD controller` 即可。不需要提前下载驱动。
488 | 
489 | ![virtio-gpu-1](https://github.com/user-attachments/assets/503e1d82-4fa9-4486-917e-73326ad7c988)
490 | ![virtio-gpu-2](https://github.com/user-attachments/assets/bf3a9af6-13d8-4f93-9d6c-d3b2dbddb37d)
491 | ![virtio-gpu-3](https://github.com/user-attachments/assets/a9006a78-838f-45bf-a556-2dba193d3c03)
492 | 
493 | </details>
494 | 
495 | ## 讨论
496 | 
497 | [![GitHub Issues](https://img.shields.io/badge/github-%23121011.svg?style=for-the-badge&logo=github&logoColor=white)](https://github.com/bin456789/reinstall/issues)
498 | [![Telegram Group](https://img.shields.io/badge/Telegram-2CA5E0?style=for-the-badge&logo=telegram&logoColor=white)](https://t.me/reinstall_os)
499 | 
500 | ## 如何修改脚本自用
501 | 
502 | 1. Fork 本仓库
503 | 2. 修改 `reinstall.sh` 和 `reinstall.bat` 开头的 `confhome` 和 `confhome_cn`
504 | 3. 修改其它代码
505 | 
506 | ## 感谢
507 | 
508 | [![Github Sponsors](https://img.shields.io/badge/sponsor-30363D?style=for-the-badge&logo=GitHub-Sponsors&logoColor=#EA4AAA)](https://github.com/sponsors/bin456789)
509 | 
510 | 感谢以下商家提供白嫖机器
511 | 
512 | [![Oracle Cloud](https://github.com/bin456789/reinstall/assets/7548515/8b430ed4-8344-4f96-b4da-c2bda031cc90)](https://www.oracle.com/cloud/)
513 | [![DartNode](https://github.com/bin456789/reinstall/assets/7548515/435d6740-bcdd-4f3a-a196-2f60ae397f17)](https://dartnode.com/)
514 | 


--------------------------------------------------------------------------------
/cloud-init-fix-onlink.sh:
--------------------------------------------------------------------------------
  1 | #!/bin/bash
  2 | # 修复 cloud-init 没有正确渲染 onlink 网关
  3 | 
  4 | set -eE
  5 | os_dir=$1
  6 | 
  7 | # 该脚本也会在 alpine live 下调用
  8 | # 防止在 alpine live 下运行 systemctl netplan 报错
  9 | systemctl() {
 10 |     if systemd-detect-virt --chroot; then
 11 |         return
 12 |     fi
 13 |     command systemctl "$@"
 14 | }
 15 | 
 16 | netplan() {
 17 |     if systemd-detect-virt --chroot; then
 18 |         return
 19 |     fi
 20 |     command netplan "$@"
 21 | }
 22 | 
 23 | insert_into_file() {
 24 |     file=$1
 25 |     location=$2
 26 |     regex_to_find=$3
 27 | 
 28 |     if [ "$location" = head ]; then
 29 |         bak=$(mktemp)
 30 |         cp "$file" "$bak"
 31 |         cat - "$bak" >"$file"
 32 |     else
 33 |         line_num=$(grep -E -n "$regex_to_find" "$file" | cut -d: -f1)
 34 | 
 35 |         found_count=$(echo "$line_num" | wc -l)
 36 |         if [ ! "$found_count" -eq 1 ]; then
 37 |             return 1
 38 |         fi
 39 | 
 40 |         case "$location" in
 41 |         before) line_num=$((line_num - 1)) ;;
 42 |         after) ;;
 43 |         *) return 1 ;;
 44 |         esac
 45 | 
 46 |         sed -i "${line_num}r /dev/stdin" "$file"
 47 |     fi
 48 | }
 49 | 
 50 | fix_netplan_conf() {
 51 |     # 修改前
 52 |     # gateway4: 1.1.1.1
 53 |     # gateway6: ::1
 54 | 
 55 |     # 修改后
 56 |     # routes:
 57 |     #   - to: 0.0.0.0/0
 58 |     #     via: 1.1.1.1
 59 |     #     on-link: true
 60 |     # routes:
 61 |     #   - to: ::/0
 62 |     #     via: ::1
 63 |     #     on-link: true
 64 |     conf=$os_dir/etc/netplan/50-cloud-init.yaml
 65 |     if ! [ -f "$conf" ]; then
 66 |         return
 67 |     fi
 68 | 
 69 |     # 判断 bug 是否已经修复
 70 |     if grep -q 'on-link:' "$conf"; then
 71 |         return
 72 |     fi
 73 | 
 74 |     # 获取网关
 75 |     gateways=$(grep 'gateway[4|6]:' "$conf" | awk '{print $2}')
 76 |     if [ -z "$gateways" ]; then
 77 |         return
 78 |     fi
 79 | 
 80 |     # 获取缩进
 81 |     spaces=$(grep 'gateway[4|6]:' "$conf" | head -1 | grep -o '^[[:space:]]*')
 82 | 
 83 |     {
 84 |         # 网关头部
 85 |         cat <<EOF
 86 | ${spaces}routes:
 87 | EOF
 88 |         # 网关条目
 89 |         for gateway in $gateways; do
 90 |             # debian 11 的 netplan 不支持 to: default
 91 |             case $gateway in
 92 |             *.*) to='0.0.0.0/0' ;;
 93 |             *:*) to='::/0' ;;
 94 |             esac
 95 | 
 96 |             cat <<EOF
 97 | ${spaces}  - to: $to
 98 | ${spaces}    via: $gateway
 99 | ${spaces}    on-link: true
100 | EOF
101 |         done
102 |     } | insert_into_file "$conf" before 'match:'
103 | 
104 |     # 删除原来的条目
105 |     sed -i '/gateway[4|6]:/d' "$conf"
106 | 
107 |     # 重新应用配置
108 |     if command -v netplan && {
109 |         systemctl -q is-enabled systemd-networkd || systemctl -q is-enabled NetworkManager
110 |     }; then
111 |         netplan apply
112 |     fi
113 | }
114 | 
115 | fix_networkd_conf() {
116 |     # 修改前 gentoo
117 |     # [Route]
118 |     # Gateway=1.1.1.1
119 |     # Gateway=2602::1
120 | 
121 |     # 修改前 arch
122 |     # [Route]
123 |     # Gateway=1.1.1.1
124 |     #
125 |     # [Route]
126 |     # Gateway=2602::1
127 | 
128 |     # 修改后
129 |     # [Route]
130 |     # Gateway=1.1.1.1
131 |     # GatewayOnLink=yes
132 |     #
133 |     # [Route]
134 |     # Gateway=2602::1
135 |     # GatewayOnLink=yes
136 | 
137 |     if ! confs=$(ls "$os_dir"/etc/systemd/network/10-cloud-init-*.network 2>/dev/null); then
138 |         return
139 |     fi
140 | 
141 |     for conf in $confs; do
142 |         # 判断 bug 是否已经修复
143 |         if grep -q '^GatewayOnLink=' "$conf"; then
144 |             return
145 |         fi
146 | 
147 |         # 获取网关
148 |         gateways=$(grep '^Gateway=' "$conf" | cut -d= -f2)
149 |         if [ -z "$gateways" ]; then
150 |             return
151 |         fi
152 | 
153 |         # 删除原来的条目
154 |         sed -i '/^\[Route\]/d; /^Gateway=/d; /^GatewayOnLink=/d' "$conf"
155 | 
156 |         # 创建新条目
157 |         for gateway in $gateways; do
158 |             echo "
159 | [Route]
160 | Gateway=$gateway
161 | GatewayOnLink=yes
162 | "
163 |         done >>"$conf"
164 |     done
165 | 
166 |     # 重新应用配置
167 |     # networkctl reload 不起作用
168 |     if systemctl -q is-enabled systemd-networkd; then
169 |         systemctl restart systemd-networkd
170 |     fi
171 | }
172 | 
173 | fix_wicked_conf() {
174 |     # https://github.com/openSUSE/wicked/wiki/FAQ#q-why-wicked-does-not-set-my-default-static-route
175 | 
176 |     # 修改前
177 |     # default 1.1.1.1 - -
178 |     # default 2602::1 - -
179 | 
180 |     # 修改后
181 |     # 1.1.1.1 - -
182 |     # 2602::1 - -
183 |     # default 1.1.1.1 - -
184 |     # default 2602::1 - -
185 | 
186 |     if ! confs=$(ls "$os_dir/etc/sysconfig/network/ifroute-"* 2>/dev/null); then
187 |         return
188 |     fi
189 | 
190 |     for conf in $confs; do
191 |         # 判断 bug 是否已经修复
192 |         if grep -v 'default' "$conf" | grep -q '-'; then
193 |             return
194 |         fi
195 | 
196 |         # 获取网关
197 |         gateways=$(awk '$1=="default" {print $2}' "$conf")
198 |         if [ -z "$gateways" ]; then
199 |             return
200 |         fi
201 | 
202 |         # 创建新条目
203 |         for gateway in $gateways; do
204 |             echo "$gateway - -"
205 |         done | insert_into_file "$conf" head
206 |     done
207 | 
208 |     # 重新应用配置
209 |     if systemctl -q is-enabled wicked; then
210 |         systemctl restart wicked
211 |     fi
212 | }
213 | 
214 | # ubuntu 18.04 cloud-init 版本 23.1.2,因此不用处理
215 | 
216 | # debian 10/11 云镜像原本用 ifupdown + resolvconf,脚本改成用 netplan + networkd/resolved
217 | # debian 12 云镜像: netplan + networkd/resolved
218 | # 23.1.1 修复
219 | fix_netplan_conf
220 | 
221 | # arch: networkd/resolved
222 | # gentoo: networkd/resolved
223 | # 24.2 修复
224 | # 只需对云镜像处理
225 | # 因为普通安装用的是 alpine 的 cloud-init,版本够新,不用处理
226 | fix_networkd_conf
227 | 
228 | # opensuse 15.5: ifcfg + netconfig (dns) + wicked
229 | fix_wicked_conf
230 | 


--------------------------------------------------------------------------------
/cloud-init.yaml:
--------------------------------------------------------------------------------
 1 | #cloud-config
 2 | datasource_list: [None]
 3 | timezone: Asia/Shanghai
 4 | disable_root: false
 5 | ssh_pwauth: true
 6 | users:
 7 |   - name: root
 8 |     lock_passwd: false
 9 | chpasswd:
10 |   expire: false
11 |   # <= cloud-init 22.2.x 需要
12 |   list: |
13 |     root:@PASSWORD@
14 |   users:
15 |     - name: root
16 |       password: "@PASSWORD@"
17 |       type: hash
18 | runcmd:
19 |   # opensuse tumbleweed 镜像有 /etc/ssh/sshd_config.d/ 文件夹,没有 /etc/ssh/sshd_config,有/usr/etc/ssh/sshd_config
20 |   # opensuse tumbleweed cloud-init 直接创建并写入 /etc/ssh/sshd_config,造成默认配置丢失
21 |   # 下面这行删除 clout-init 创建的 sshd_config
22 |   - test $(wc -l </etc/ssh/sshd_config) -le 1 && cat /etc/ssh/sshd_config >>/etc/ssh/sshd_config.d/50-cloud-init.conf && rm -f /etc/ssh/sshd_config
23 |   - echo "PermitRootLogin yes" >/etc/ssh/sshd_config.d/01-permitrootlogin.conf 2>/dev/null || sed -Ei 's/^#?PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config
24 |   - echo "Port @SSH_PORT@" >/etc/ssh/sshd_config.d/01-change-ssh-port.conf || sed -Ei 's/^#?Port .*/Port @SSH_PORT@/' /etc/ssh/sshd_config
25 |   # 已创建的 ssh 连接会沿用旧的配置(未开启密码登录),这时即使输入正确的密码,也会提示 Access Denied
26 |   # systemctl restart sshd 只会重启监听进程,不会关闭已创建的连接(子进程)
27 |   - pkill sshd || true
28 |   # daemon-reload 会刷新 /run/systemd/generator/ssh.socket.d/addresses.conf
29 |   - systemctl daemon-reload
30 |   - for s in ssh.socket ssh.service sshd.socket sshd.service; do systemctl is-enabled $s 2>/dev/null && systemctl restart $s && break; done
31 |   # 删除有密码的行
32 |   - sed -i -e '/^[[:space:]]*password:/d' -e '/[[:space:]]*root:/d' /etc/cloud/cloud.cfg.d/99_fallback.cfg
33 |   - touch /etc/cloud/cloud-init.disabled
34 |   # ubuntu 镜像运行 echo -e '\nDone' ,-e 会被显示出来
35 |   # 加 true 因为有的 tty 不可写
36 |   - for tty in tty0 ttyS0 ttyAMA0; do [ -c /dev/$tty ] && printf '\n%s\n' 'reinstall done' >/dev/$tty || true; done
37 | 


--------------------------------------------------------------------------------
/debian.cfg:
--------------------------------------------------------------------------------
  1 | #_preseed_V1
  2 | # shellcheck disable=SC1091,SC2148
  3 | # https://www.debian.org/releases/stable/amd64/apbs04.zh-cn.html
  4 | # https://www.debian.org/releases/stable/example-preseed.txt
  5 | # https://preseed.debian.net/debian-preseed/bookworm/amd64-main-full.txt
  6 | # 需要留意 kali initrd 自带的 /preseed.cfg
  7 | 
  8 |   # 下面这行语句无效,因为本行后面有反斜杠,前面有空格(安装器认为不算注释)\
  9 | d-i debian-installer/locale string en_US
 10 | 
 11 | # B.4.1. 本地化
 12 | d-i debian-installer/locale string en_US
 13 | d-i keyboard-configuration/xkb-keymap select us
 14 | 
 15 | # B.4.2. 网络设置
 16 | d-i netcfg/get_hostname string unassigned-hostname
 17 | d-i netcfg/get_domain string unassigned-domain
 18 | d-i netcfg/hostname string localhost
 19 | 
 20 | # B.4.3. 网络控制台
 21 | 
 22 | # B.4.4. 镜像设置
 23 | d-i mirror/country string manual
 24 | # d-i mirror/http/hostname string deb.debian.org
 25 | 
 26 | # B.4.5. 帐号设置
 27 | d-i passwd/make-user boolean false
 28 | # 单纯为了跳过设置,实际上是在 partman/early_command 里设置密码,preseed/early_command 无法设置密码
 29 | # 注意如果用 ssh key 后面还要删除密码
 30 | d-i passwd/root-password password ''
 31 | d-i passwd/root-password-again password ''
 32 | # kali 需要下面这行,否则会提示输入用户名
 33 | d-i passwd/root-login boolean true
 34 | 
 35 | # B.4.6. 时钟与时区设置
 36 | d-i time/zone string Asia/Shanghai
 37 | 
 38 | # B.4.7. 分区
 39 | d-i partman-auto/method string regular
 40 | d-i partman-lvm/device_remove_lvm boolean true
 41 | d-i partman-md/device_remove_md boolean true
 42 | d-i partman-partitioning/confirm_write_new_label boolean true
 43 | d-i partman/choose_partition select finish
 44 | d-i partman/confirm boolean true
 45 | d-i partman/confirm_nooverwrite boolean true
 46 | 
 47 | # vm 原有系统是 bios + gpt,切换成 efi,用 iso 重装,需要确认此项
 48 | # 用脚本重装的话,强制安装在第二个硬盘上也可能会遇到?
 49 | d-i partman-efi/non_efi_system boolean true
 50 | 
 51 | ### Description: Do you want to return to the partitioning menu?
 52 | #   You have not selected any partitions for use as swap space. Enabling swap
 53 | #   space is recommended so that the system can make better use of the
 54 | #   available physical memory, and so that it behaves better when physical
 55 | #   memory is scarce. You may experience installation problems if you do not
 56 | #   have enough physical memory.
 57 | #   .
 58 | #   If you do not go back to the partitioning menu and assign a swap partition,
 59 | #   the installation will continue without swap space.
 60 | # 坑的一比
 61 | # 不是确认是否 no_swap
 62 | # 而是 recipe no_swap 时,确认是否返回上一级重新分区
 63 | # 选择 true 就一直死循环
 64 | d-i partman-basicfilesystems/no_swap boolean false
 65 | 
 66 | # 最小值 膨胀权重 最大值
 67 | # https://salsa.debian.org/installer-team/partman-auto/-/blob/master/recipes/atomic?ref_type=heads
 68 | # https://salsa.debian.org/installer-team/partman-auto/-/blob/master/recipes-amd64-efi/atomic?ref_type=heads
 69 | # shellcheck disable=SC1083,SC2086,SC2154
 70 | d-i partman-auto/expert_recipe_efi string efi :: \
 71 |     106 1 106 free \
 72 |     $iflabel{ gpt } method{ efi } format{ } . \
 73 |     1 1 -1 $default_filesystem \
 74 |     method{ format } format{ } use_filesystem{ } $default_filesystem{ } mountpoint{ / } .
 75 | 
 76 | # shellcheck disable=SC1083,SC2086,SC2154
 77 | d-i partman-auto/expert_recipe_bios string bios :: \
 78 |     1 1 1 free \
 79 |     $iflabel{ gpt } method{ biosgrub } . \
 80 |     1 1 -1 $default_filesystem \
 81 |     method{ format } format{ } use_filesystem{ } $default_filesystem{ } mountpoint{ / } .
 82 | 
 83 | # B.4.8. 基本系统安装
 84 | 
 85 | # B.4.9. 设置 apt
 86 | d-i apt-setup/non-free boolean true
 87 | d-i apt-setup/non-free-firmware boolean true
 88 | d-i apt-setup/contrib boolean true
 89 | d-i apt-setup/enable-source-repositories boolean false
 90 | # kali 不要设置
 91 | # d-i apt-setup/security_host string security.debian.org
 92 | 
 93 | # B.4.10. 选择软件包
 94 | tasksel tasksel/first multiselect ssh-server
 95 | d-i pkgsel/upgrade select none
 96 | 
 97 | # B.4.11. 安装 bootloader
 98 | # 添加 bootx64.efi
 99 | d-i grub-installer/force-efi-extra-removable boolean true
100 | 
101 | # B.4.12. 完成安装
102 | d-i finish-install/reboot_in_progress note
103 | 
104 | # B.4.13. 预置其他的软件包
105 | 
106 | # 其他设置
107 | # d-i anna/standard_modules boolean false
108 | # d-i anna/choose_modules string network-console
109 | # d-i network-console/password password 123@@@
110 | # d-i network-console/password-again password 123@@@
111 | 
112 | # B.5.1. 安装过程中运行用户命令
113 | # 注意所有命令都会合并成一行命令
114 | 
115 | # 最后的 true; \ 没什么用,只是让 vscode 代码高亮不报错误
116 | 
117 | # 有 /cdrom/simple-cdd 才安装 simple-cdd-profiles
118 | # 不然安装时 control 脚本会报错:
119 | # Loading simple-cdd-profiles failed for unknown reasons
120 | d-i preseed/early_command string true; \
121 |     if [ -d /cdrom/simple-cdd ]; then anna-install simple-cdd-profiles; fi
122 | 
123 | # debian 11 initrd 没有 xargs awk
124 | # debian 12 initrd 没有 xargs
125 | # efi 分区大小未改变时,不会被格式化,因此需要手动删除旧系统的 efi 文件
126 | # os-prober 卡太久,因此跳过
127 | d-i partman/early_command string true; \
128 |     eval "$(grep -o 'extra_confhome=[^ ]*' /proc/cmdline | sed 's/^extra_//')"; \
129 | 
130 |     postinst=/var/lib/dpkg/info/bootstrap-base.postinst; \
131 |     cp $postinst $postinst.orig; \
132 |     true >$postinst; \
133 | 
134 |     swapfile=/target/swapfile; \
135 |     mem=$(grep ^MemTotal: /proc/meminfo | { read -r _ y _; echo "$y"; }); \
136 |     mem=$((mem / 1024)); \
137 |     swap_size=$((512 - mem)); \
138 |     [ $swap_size -gt 0 ] && echo "fallocate -l ${swap_size}M $swapfile; mkswap $swapfile; swapon $swapfile" >>$postinst; \
139 | 
140 |     echo "swapoff -a; rm -f $swapfile" >/usr/lib/finish-install.d/95swapoff; \
141 |     chmod a+x /usr/lib/finish-install.d/95swapoff; \
142 | 
143 |     echo "rm -rf /target/boot/efi/*; $postinst.orig" >>$postinst; \
144 | 
145 |     xda=$(sh /get-xda.sh); \
146 |     debconf-set partman-auto/disk "/dev/$xda"; \
147 |     debconf-set grub-installer/bootdev "/dev/$xda"; \
148 |     rm -rf /usr/sbin/fdisk /usr/sbin/sfdisk; \
149 | 
150 |     ttys=$(sh /ttys.sh console=); \
151 |     debconf-set debian-installer/add-kernel-opts "$ttys"; \
152 | 
153 |     eths=$(cd /dev/netconf/ && ls); \
154 | 
155 |     sh /can_use_cloud_kernel.sh "$xda" $eths || debconf-set base-installer/kernel/image "$(debconf-get base-installer/kernel/image | sed 's/-cloud//')"; \
156 | 
157 |     [ -d /sys/firmware/efi ] && debconf-set partman-auto/expert_recipe "$(debconf-get partman-auto/expert_recipe_efi)"; \
158 |     [ -d /sys/firmware/efi ] || debconf-set partman-auto/expert_recipe "$(debconf-get partman-auto/expert_recipe_bios)"; \
159 | 
160 |     debconf-set passwd/root-password-crypted "$(cat /configs/password-linux-sha512)"; \
161 | 
162 |     true >/bin/os-prober
163 | 
164 | # kali ssh 默认关闭
165 | # 另一种方法处理 cloudcone
166 | # if [ "$link_grub_dir" = 1 ]; then mkdir /target/boot/grub2; echo 'chainloader (hd0)+1' >/target/boot/grub2/grub.cfg; fi; \
167 | # debian 9 tar 不支持 --strip-components
168 | d-i preseed/late_command string true; \
169 |     for str in $(grep -wo "extra_[^ ]*" /proc/cmdline | sed 's/^extra_//'); do eval "$str"; done; \
170 | 
171 |     if [ "$elts" = 1 ]; then sed -i "s|deb\.freexian\.com/extended-lts|$deb_mirror|" /target/etc/apt/sources.list; fi; \
172 | 
173 |     if [ "$link_grub_dir" = 1 ]; then ln -s grub /target/boot/grub2; fi; \
174 | 
175 |     in-target systemctl enable ssh; \
176 | 
177 |     if [ -s /configs/ssh_keys ]; then \
178 |         (umask 077; mkdir -p /target/root/.ssh; cat /configs/ssh_keys >/target/root/.ssh/authorized_keys); \
179 |         in-target passwd -d root; \
180 |     else \
181 |         echo "PermitRootLogin yes" >/target/etc/ssh/sshd_config.d/01-permitrootlogin.conf || \
182 |         echo "PermitRootLogin yes" >>/target/etc/ssh/sshd_config; \
183 |     fi; \
184 | 
185 |     if [ -n "$ssh_port" ] && ! [ "$ssh_port" = 22 ]; then \
186 |         echo "Port $ssh_port" >/target/etc/ssh/sshd_config.d/01-change-ssh-port.conf || \
187 |         echo "Port $ssh_port" >>/target/etc/ssh/sshd_config; \
188 |     fi; \
189 | 
190 |     if [ -s /configs/frpc.toml ]; then \
191 |         url=$(sh /get-frpc-url.sh linux); \
192 |         basename=$(echo "$url" | sed 's,.*/,,' | sed 's,\.tar\.gz,,'); \
193 |         mkdir -p /target/usr/local/bin; \
194 |         mkdir -p /target/usr/local/etc/frpc; \
195 |         for i in {1..5}; do \
196 |             wget -O /target/frpc.tar.gz "$url" && break; \
197 |         done; \
198 |         tar xzf /target/frpc.tar.gz "$basename/frpc" -O >/target/usr/local/bin/frpc; \
199 |         rm -f /target/frpc.tar.gzx; \
200 |         chmod a+x /target/usr/local/bin/frpc; \
201 |         cp /configs/frpc.toml /target/usr/local/etc/frpc/; \
202 |         cp /frpc.service /target/etc/systemd/system/; \
203 |         in-target systemctl enable frpc; \
204 |     fi; \
205 | 
206 |     cp /fix-eth-name.sh /target/; \
207 |     cp /fix-eth-name.service /target/etc/systemd/system/; \
208 |     in-target systemctl enable fix-eth-name
209 | 


--------------------------------------------------------------------------------
/fix-eth-name.initd:
--------------------------------------------------------------------------------
 1 | #!/sbin/openrc-run
 2 | 
 3 | Description="Fix Eth Name"
 4 | 
 5 | # https://gitlab.alpinelinux.org/alpine/aports/-/blob/master/main/openrc/networking.initd
 6 | # https://gitlab.alpinelinux.org/alpine/aports/-/blob/master/main/dhcpcd/dhcpcd.initd
 7 | depend() {
 8 |     need localmount
 9 |     want dev-settle
10 | 
11 |     after bootmisc hwdrivers modules
12 |     before net networking dhcpcd
13 | }
14 | 
15 | start() {
16 |     ebegin "Fix Eth Name"
17 |     ash /fix-eth-name.sh
18 |     eend $?
19 | }
20 | 
21 | start_post() {
22 |     rc-service fix-eth-name zap
23 |     rc-update del fix-eth-name boot
24 |     rm -f /etc/init.d/fix-eth-name
25 |     rm -f /fix-eth-name.sh
26 | }
27 | 


--------------------------------------------------------------------------------
/fix-eth-name.service:
--------------------------------------------------------------------------------
 1 | [Unit]
 2 | Description=Fix Eth Name
 3 | ConditionPathExists=/fix-eth-name.sh
 4 | 
 5 | After=dbus.service
 6 | 
 7 | Before=cloud-init-local.service
 8 | Before=network.service
 9 | Before=networking.service
10 | Before=systemd-networkd.service
11 | Before=NetworkManager.service
12 | Before=wickedd-auto4.service
13 | Before=wickedd-dhcp4.service
14 | Before=wickedd-dhcp6.service
15 | Before=wickedd.service
16 | 
17 | Before=network.target
18 | 
19 | [Service]
20 | Type=oneshot
21 | ExecStart=/usr/bin/env bash /fix-eth-name.sh
22 | ExecStart=/usr/bin/env rm -f /fix-eth-name.sh
23 | ExecStart=/usr/bin/env rm -f /etc/systemd/system/fix-eth-name.service
24 | ExecStart=/usr/bin/env rm -f /etc/systemd/system/multi-user.target.wants/fix-eth-name.service
25 | ExecStart=/usr/bin/env rm -f /lib/systemd/system-preset/01-fix-eth-name.preset
26 | ExecStart=/usr/bin/env rm -f /usr/lib/systemd/system-preset/01-fix-eth-name.preset
27 | 
28 | [Install]
29 | WantedBy=multi-user.target
30 | 


--------------------------------------------------------------------------------
/fix-eth-name.sh:
--------------------------------------------------------------------------------
  1 | #!/usr/bin/env bash
  2 | # shellcheck shell=dash
  3 | # shellcheck disable=SC3001,SC3010
  4 | # alpine 使用 busybox ash
  5 | 
  6 | set -eE
  7 | 
  8 | # openeuler 需等待 udev 将网卡名从 eth0 改为 enp3s0
  9 | sleep 10
 10 | # 不知道有没有用
 11 | if command -v udevadm >/dev/null; then
 12 |     # udevadm trigger
 13 |     udevadm settle
 14 | elif command -v mdev >/dev/null; then
 15 |     mdev -sf
 16 | fi
 17 | 
 18 | # 本脚本在首次进入新系统后运行
 19 | # 将 trans 阶段生成的网络配置中的网卡名(eth0) 改为正确的网卡名,也适用于以下情况
 20 | # 1. alpine 要运行此脚本,因为安装后的内核可能有 netboot 没有的驱动
 21 | # 2. dmit debian 普通内核(安装时)和云内核网卡名不一致
 22 | #    https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=928923
 23 | 
 24 | # todo: 删除 cloud-init
 25 | 
 26 | to_lower() {
 27 |     tr '[:upper:]' '[:lower:]'
 28 | }
 29 | 
 30 | retry() {
 31 |     local max_try=$1
 32 |     shift
 33 | 
 34 |     for i in $(seq "$max_try"); do
 35 |         if "$@"; then
 36 |             return
 37 |         else
 38 |             ret=$?
 39 |             if [ "$i" -ge "$max_try" ]; then
 40 |                 return $ret
 41 |             fi
 42 |             sleep 1
 43 |         fi
 44 |     done
 45 | }
 46 | 
 47 | # openeuler 本脚本运行一秒后才有 enp3s0
 48 | # 用 systemd-analyze plot >a.svg 发现 sys-subsystem-net-devices-enp3s0.device 也是出现在 NetworkManager 之后
 49 | # 因此需要等待网卡出现
 50 | get_ethx_by_mac() {
 51 |     mac=$(echo "$1" | to_lower)
 52 |     retry 10 _get_ethx_by_mac "$mac"
 53 | }
 54 | 
 55 | _get_ethx_by_mac() {
 56 |     if true; then
 57 |         # 过滤 azure vf (带 master ethx)
 58 |         ip -o link | grep -i "$mac" | grep -v master | awk '{print $2}' | cut -d: -f1 | grep .
 59 |         return
 60 |     else
 61 |         for i in $(cd /sys/class/net && echo *); do
 62 |             if [ "$(cat "/sys/class/net/$i/address")" = "$mac" ]; then
 63 |                 echo "$i"
 64 |                 return
 65 |             fi
 66 |         done
 67 |         return 1
 68 |     fi
 69 | }
 70 | 
 71 | fix_rh_sysconfig() {
 72 |     for file in /etc/sysconfig/network-scripts/ifcfg-eth*; do
 73 |         # 没有 ifcfg-eth* 也会执行一次,因此要判断文件是否存在
 74 |         [ -f "$file" ] || continue
 75 |         mac=$(grep ^HWADDR= "$file" | cut -d= -f2 | grep .) || continue
 76 |         ethx=$(get_ethx_by_mac "$mac") || continue
 77 | 
 78 |         proper_file=/etc/sysconfig/network-scripts/ifcfg-$ethx
 79 |         if [ "$file" != "$proper_file" ]; then
 80 |             # 更改文件内容
 81 |             sed -i "s/^DEVICE=.*/DEVICE=$ethx/" "$file"
 82 | 
 83 |             # 不要直接更改文件名,因为可能覆盖已有文件
 84 |             mv "$file" "$proper_file.tmp"
 85 |         fi
 86 |     done
 87 | 
 88 |     # 更改文件名
 89 |     for tmp_file in /etc/sysconfig/network-scripts/ifcfg-e*.tmp; do
 90 |         if [ -f "$tmp_file" ]; then
 91 |             mv "$tmp_file" "${tmp_file%.tmp}"
 92 |         fi
 93 |     done
 94 | }
 95 | 
 96 | fix_suse_sysconfig() {
 97 |     for file in /etc/sysconfig/network/ifcfg-eth*; do
 98 |         [ -f "$file" ] || continue
 99 | 
100 |         # 可能两边有引号
101 |         mac=$(grep ^LLADDR= "$file" | cut -d= -f2 | sed "s/'//g" | grep .) || continue
102 |         ethx=$(get_ethx_by_mac "$mac") || continue
103 | 
104 |         old_ethx=${file##*-}
105 |         if ! [ "$old_ethx" = "$ethx" ]; then
106 |             # 不要直接更改文件名,因为可能覆盖已有文件
107 |             for type in ifcfg ifroute; do
108 |                 old_file=/etc/sysconfig/network/$type-$old_ethx
109 |                 new_file=/etc/sysconfig/network/$type-$ethx.tmp
110 |                 # 防止没有 ifroute-eth* 导致中断脚本
111 |                 if [ -f "$old_file" ]; then
112 |                     mv "$old_file" "$new_file"
113 |                 fi
114 |             done
115 |         fi
116 |     done
117 | 
118 |     # 上面的循环结束后,再将 tmp 改成正式文件
119 |     for tmp_file in \
120 |         /etc/sysconfig/network/ifcfg-e*.tmp \
121 |         /etc/sysconfig/network/ifroute-e*.tmp; do
122 |         if [ -f "$tmp_file" ]; then
123 |             mv "$tmp_file" "${tmp_file%.tmp}"
124 |         fi
125 |     done
126 | }
127 | 
128 | fix_network_manager() {
129 |     for file in /etc/NetworkManager/system-connections/cloud-init-eth*.nmconnection; do
130 |         [ -f "$file" ] || continue
131 |         mac=$(grep ^mac-address= "$file" | cut -d= -f2 | grep .) || continue
132 |         ethx=$(get_ethx_by_mac "$mac") || continue
133 | 
134 |         proper_file=/etc/NetworkManager/system-connections/$ethx.nmconnection
135 | 
136 |         # 更改文件内容
137 |         sed -i "s/^id=.*/id=$ethx/" "$file"
138 | 
139 |         # 更改文件名
140 |         mv "$file" "$proper_file"
141 |     done
142 | }
143 | 
144 | # debian 9 IPV6 onlink 路由需要 post-up
145 | 
146 | # auto lo
147 | # iface lo inet loopback
148 | 
149 | # # mac 11:22:33:44:55:66    # 用此行匹配网卡
150 | # auto eth0
151 | # iface eth0 inet static
152 | #     address 1.1.1.1/25
153 | #     gateway 1.1.1.1
154 | #     dns-nameservers 1.1.1.1
155 | #     dns-nameservers 8.8.8.8
156 | # iface eth0 inet6 static
157 | #     address 2602:1:0:80::100/64
158 | #     gateway 2602:1:0:80::1
159 | #     post-up ip route add 2602:1:0:80::1 dev eth0
160 | #     post-up ip route add default via 2602:1:0:80::1 dev eth0
161 | #     dns-nameserver 2606:4700:4700::1111
162 | #     dns-nameserver 2001:4860:4860::8888
163 | 
164 | fix_ifupdown() {
165 |     file=/etc/network/interfaces
166 |     tmp_file=$file.tmp
167 | 
168 |     rm -f "$tmp_file"
169 | 
170 |     if [ -f "$file" ]; then
171 |         while IFS= read -r line; do
172 |             del_this_line=false
173 |             if [[ "$line" = "# mac "* ]]; then
174 |                 ethx=
175 |                 if mac=$(echo "$line" | awk '{print $NF}'); then
176 |                     ethx=$(get_ethx_by_mac "$mac") || true
177 |                 fi
178 |                 del_this_line=true
179 |             elif [[ "$line" = "iface e"* ]] ||
180 |                 [[ "$line" = "auto e"* ]] ||
181 |                 [[ "$line" = "allow-hotplug e"* ]]; then
182 |                 if [ -n "$ethx" ]; then
183 |                     line=$(echo "$line" | awk "{\$2=\"$ethx\"; print \$0}")
184 |                 fi
185 |             elif [[ "$line" = *" dev e"* ]]; then
186 |                 if [ -n "$ethx" ]; then
187 |                     # awk 会去除前面的空格
188 |                     line=$(echo "$line" | sed -E "s/[^ ]*$/$ethx/")
189 |                 fi
190 |             fi
191 |             if ! $del_this_line; then
192 |                 echo "$line" >>"$tmp_file"
193 |             fi
194 |         done <"$file"
195 | 
196 |         mv "$tmp_file" "$file"
197 |     fi
198 | }
199 | 
200 | fix_netplan() {
201 |     file=/etc/netplan/50-cloud-init.yaml
202 |     tmp_file=$file.tmp
203 | 
204 |     rm -f "$tmp_file"
205 | 
206 |     if [ -f "$file" ]; then
207 |         while IFS= read -r line; do
208 |             if echo "$line" | grep -Eq '^[[:space:]]+macaddress:'; then
209 |                 # 得到正确的网卡名
210 |                 mac=$(echo "$line" | awk '{print $NF}' | sed 's/"//g')
211 |                 ethx=$(get_ethx_by_mac "$mac") || true
212 |             elif echo "$line" | grep -Eq '^[[:space:]]+eth[0-9]+:'; then
213 |                 # 改成正确的网卡名
214 |                 if [ -n "$ethx" ]; then
215 |                     line=$(echo "$line" | sed -E "s/[^[:space:]]+/$ethx:/")
216 |                 fi
217 |             fi
218 |             echo "$line" >>"$tmp_file"
219 | 
220 |             # 删除 set-name 不过这一步在 trans 已完成
221 |             # 因为 netplan-generator 会在 systemd generator 阶段就根据 netplan 配置重命名网卡
222 |             # systemd generator 阶段比本脚本和 systemd-networkd 更早运行
223 | 
224 |             # 倒序
225 |         done < <(grep -Ev "^[[:space:]]+set-name:" "$file" | tac)
226 | 
227 |         # 再倒序回来
228 |         tac "$tmp_file" >"$file"
229 |         rm -f "$tmp_file"
230 | 
231 |         # 通过 systemd netplan generator 生成 /run/systemd/network/10-netplan-enp3s0.network
232 |         systemctl daemon-reload
233 |     fi
234 | }
235 | 
236 | fix_systemd_networkd() {
237 |     for file in /etc/systemd/network/10-cloud-init-eth*.network; do
238 |         [ -f "$file" ] || continue
239 |         mac=$(grep ^MACAddress= "$file" | cut -d= -f2 | grep .) || continue
240 |         ethx=$(get_ethx_by_mac "$mac") || continue
241 | 
242 |         proper_file=/etc/systemd/network/10-$ethx.network
243 | 
244 |         # 更改文件内容
245 |         sed -Ei "s/^Name=eth[0-9]+/Name=$ethx/" "$file"
246 | 
247 |         # 更改文件名
248 |         mv "$file" "$proper_file"
249 |     done
250 | }
251 | 
252 | fix_rh_sysconfig
253 | fix_suse_sysconfig
254 | fix_network_manager
255 | fix_ifupdown
256 | fix_netplan
257 | fix_systemd_networkd
258 | 


--------------------------------------------------------------------------------
/frpc-example.toml:
--------------------------------------------------------------------------------
 1 | serverAddr = "YOUR_FRP_SERVER_IP"
 2 | serverPort = 7000
 3 | auth.token = "YOUR_FRP_TOKEN"
 4 | 
 5 | [[proxies]]
 6 | name = "ssh"
 7 | type = "tcp"
 8 | localIP = "127.0.0.1"
 9 | localPort = 22
10 | remotePort = 2222
11 | 
12 | [[proxies]]
13 | name = "rdp_tcp"
14 | type = "tcp"
15 | localIP = "127.0.0.1"
16 | localPort = 3389
17 | remotePort = 33890
18 | 
19 | [[proxies]]
20 | name = "rdp_udp"
21 | type = "udp"
22 | localIP = "127.0.0.1"
23 | localPort = 3389
24 | remotePort = 33890
25 | 


--------------------------------------------------------------------------------
/frpc.service:
--------------------------------------------------------------------------------
 1 | # https://github.com/archlinuxcn/repo/blob/master/archlinuxcn/frp/frpc.service
 2 | 
 3 | [Unit]
 4 | Description=Frp Client Service
 5 | After=network-online.target
 6 | Wants=network-online.target
 7 | 
 8 | [Service]
 9 | Type=simple
10 | User=nobody
11 | Restart=on-failure
12 | RestartSec=5s
13 | ExecStart=/usr/local/bin/frpc -c /usr/local/etc/frpc/frpc.toml
14 | ExecReload=/usr/local/bin/frpc reload -c /usr/local/etc/frpc/frpc.toml
15 | 
16 | [Install]
17 | WantedBy=multi-user.target
18 | 


--------------------------------------------------------------------------------
/get-frpc-url.sh:
--------------------------------------------------------------------------------
 1 | #!/bin/ash
 2 | # shellcheck shell=dash
 3 | # trans.sh/debian.cfg 共用此脚本
 4 | 
 5 | # debian 9 不支持 set -E
 6 | set -e
 7 | 
 8 | is_in_china() {
 9 |     grep -q 1 /dev/netconf/*/is_in_china
10 | }
11 | 
12 | is_ipv6_only() {
13 |     ! grep -q 1 /dev/netconf/eth*/ipv4_has_internet
14 | }
15 | 
16 | get_frpc_url() {
17 |     # 传入 windows 或者 linux
18 |     local os_type=$1
19 |     local nt_ver=$2
20 | 
21 |     is_need_old_version() {
22 |         [ "$nt_ver" = "6.0" ] || [ "$nt_ver" = "6.1" ]
23 |     }
24 | 
25 |     version=$(
26 |         if is_need_old_version; then
27 |             echo 0.54.0
28 |         else
29 |             # debian 11 initrd 没有 xargs awk
30 |             # debian 12 initrd 没有 xargs
31 |             # github 不支持 ipv6
32 |             if is_in_china || is_ipv6_only; then
33 |                 wget -O- https://mirrors.nju.edu.cn/github-release/fatedier/frp/LatestRelease/frp_sha256_checksums.txt |
34 |                     grep -m1 frp_ | cut -d_ -f2
35 |             else
36 |                 # https://api.github.com/repos/fatedier/frp/releases/latest 有请求次数限制
37 | 
38 |                 # root@localhost:~# wget --spider -S https://github.com/fatedier/frp/releases/latest 2>&1 | grep Location:
39 |                 #   Location: https://github.com/fatedier/frp/releases/tag/v0.62.0
40 |                 # Location: https://github.com/fatedier/frp/releases/tag/v0.62.0 [following]  # 原版 wget 多了这行
41 | 
42 |                 wget --spider -S https://github.com/fatedier/frp/releases/latest 2>&1 |
43 |                     grep -m1 '^  Location:' | sed 's,.*/tag/v,,'
44 |             fi
45 |         fi
46 |     )
47 | 
48 |     if [ -z "$version" ]; then
49 |         echo 'cannot find version'
50 |         return 1
51 |     fi
52 | 
53 |     suffix=$(
54 |         case "$os_type" in
55 |         linux) echo tar.gz ;;
56 |         windows) echo zip ;;
57 |         esac
58 |     )
59 | 
60 |     mirror=$(
61 |         # nju 没有 win7 用的旧版
62 |         # github 不支持 ipv6
63 |         # jsdelivr 不支持 github releases 文件
64 |         if is_ipv6_only; then
65 |             if is_need_old_version; then
66 |                 echo 'NOT_SUPPORT'
67 |                 return 1
68 |             else
69 |                 echo https://mirrors.nju.edu.cn/github-release/fatedier/frp
70 |             fi
71 |         else
72 |             if is_in_china; then
73 |                 if is_need_old_version; then
74 |                     echo https://github.com/fatedier/frp/releases/download
75 |                 else
76 |                     echo https://mirrors.nju.edu.cn/github-release/fatedier/frp
77 |                 fi
78 |             else
79 |                 echo https://github.com/fatedier/frp/releases/download
80 |             fi
81 |         fi
82 |     )
83 | 
84 |     arch=$(
85 |         case "$(uname -m)" in
86 |         x86_64) echo amd64 ;;
87 |         aarch64) echo arm64 ;;
88 |         esac
89 |     )
90 | 
91 |     filename=frp_${version}_${os_type}_${arch}.$suffix
92 | 
93 |     echo "${mirror}/v${version}/${filename}"
94 | }
95 | 
96 | get_frpc_url "$@"
97 | 


--------------------------------------------------------------------------------
/get-xda.sh:
--------------------------------------------------------------------------------
 1 | #!/bin/sh
 2 | # debian ubuntu redhat 安装模式共用此脚本
 3 | # alpine 未用到此脚本
 4 | 
 5 | get_all_disks() {
 6 |     # shellcheck disable=SC2010
 7 |     ls /sys/block/ | grep -Ev '^(loop|sr|nbd)'
 8 | }
 9 | 
10 | get_xda() {
11 |     # 如果没找到 main_disk 或 xda
12 |     # 返回假的值,防止意外地格式化全部盘
13 |     eval "$(grep -o 'extra_main_disk=[^ ]*' /proc/cmdline | sed 's/^extra_//')"
14 | 
15 |     if [ -z "$main_disk" ]; then
16 |         echo 'MAIN_DISK_NOT_FOUND'
17 |         return 1
18 |     fi
19 | 
20 |     for disk in $(get_all_disks); do
21 |         if fdisk -l "/dev/$disk" | grep -iq "$main_disk"; then
22 |             echo "$disk"
23 |             return
24 |         fi
25 |     done
26 | 
27 |     echo 'XDA_NOT_FOUND'
28 |     return 1
29 | }
30 | 
31 | get_xda
32 | 


--------------------------------------------------------------------------------
/initrd-network.sh:
--------------------------------------------------------------------------------
  1 | #!/bin/ash
  2 | # shellcheck shell=dash
  3 | # alpine/debian initrd 共用此脚本
  4 | 
  5 | # accept_ra 接收 RA + 自动配置网关
  6 | # autoconf  自动配置地址,依赖 accept_ra
  7 | 
  8 | mac_addr=$1
  9 | ipv4_addr=$2
 10 | ipv4_gateway=$3
 11 | ipv6_addr=$4
 12 | ipv6_gateway=$5
 13 | is_in_china=$6
 14 | 
 15 | DHCP_TIMEOUT=15
 16 | DNS_FILE_TIMEOUT=5
 17 | TEST_TIMEOUT=10
 18 | 
 19 | # 检测是否有网络是通过检测这些 IP 的端口是否开放
 20 | # 因为 debian initrd 没有 nslookup
 21 | # 改成 generate_204?但检测网络时可能 resolv.conf 为空
 22 | # HTTP 80
 23 | # HTTPS/DOH 443
 24 | # DOT 853
 25 | if $is_in_china; then
 26 |     ipv4_dns1='223.5.5.5'
 27 |     ipv4_dns2='119.29.29.29' # 不开放 853
 28 |     ipv6_dns1='2400:3200::1'
 29 |     ipv6_dns2='2402:4e00::' # 不开放 853
 30 | else
 31 |     ipv4_dns1='1.1.1.1'
 32 |     ipv4_dns2='8.8.8.8' # 不开放 80
 33 |     ipv6_dns1='2606:4700:4700::1111'
 34 |     ipv6_dns2='2001:4860:4860::8888' # 不开放 80
 35 | fi
 36 | 
 37 | # 找到主网卡
 38 | # debian 11 initrd 没有 xargs awk
 39 | # debian 12 initrd 没有 xargs
 40 | get_ethx() {
 41 |     # 过滤 azure vf (带 master ethx)
 42 |     # 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000\    link/ether 60:45:bd:21:8a:51 brd ff:ff:ff:ff:ff:ff
 43 |     # 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP800> mtu 1500 qdisc mq master eth0 state UP qlen 1000\    link/ether 60:45:bd:21:8a:51 brd ff:ff:ff
 44 |     if false; then
 45 |         ip -o link | grep -i "$mac_addr" | grep -v master | awk '{print $2}' | cut -d: -f1 | grep .
 46 |     else
 47 |         ip -o link | grep -i "$mac_addr" | grep -v master | cut -d' ' -f2 | cut -d: -f1 | grep .
 48 |     fi
 49 | }
 50 | 
 51 | get_ipv4_gateway() {
 52 |     # debian 11 initrd 没有 xargs awk
 53 |     # debian 12 initrd 没有 xargs
 54 |     ip -4 route show default dev "$ethx" | head -1 | cut -d ' ' -f3
 55 | }
 56 | 
 57 | get_ipv6_gateway() {
 58 |     # debian 11 initrd 没有 xargs awk
 59 |     # debian 12 initrd 没有 xargs
 60 |     ip -6 route show default dev "$ethx" | head -1 | cut -d ' ' -f3
 61 | }
 62 | 
 63 | get_first_ipv4_addr() {
 64 |     # debian 11 initrd 没有 xargs awk
 65 |     # debian 12 initrd 没有 xargs
 66 |     if false; then
 67 |         ip -4 -o addr show scope global dev "$ethx" | head -1 | awk '{print $4}'
 68 |     else
 69 |         ip -4 -o addr show scope global dev "$ethx" | head -1 | grep -o '[0-9\.]*/[0-9]*'
 70 |     fi
 71 | }
 72 | 
 73 | get_first_ipv4_gateway() {
 74 |     # debian 11 initrd 没有 xargs awk
 75 |     # debian 12 initrd 没有 xargs
 76 |     if false; then
 77 |         ip -4 route show default dev "$ethx" | head -1 | awk '{print $3}'
 78 |     else
 79 |         ip -4 route show default dev "$ethx" | head -1 | cut -d' ' -f3
 80 |     fi
 81 | }
 82 | 
 83 | remove_netmask() {
 84 |     cut -d/ -f1
 85 | }
 86 | 
 87 | get_first_ipv6_addr() {
 88 |     # debian 11 initrd 没有 xargs awk
 89 |     # debian 12 initrd 没有 xargs
 90 |     if false; then
 91 |         ip -6 -o addr show scope global dev "$ethx" | head -1 | awk '{print $4}'
 92 |     else
 93 |         ip -6 -o addr show scope global dev "$ethx" | head -1 | grep -o '[0-9a-f\:]*/[0-9]*'
 94 |     fi
 95 | }
 96 | 
 97 | get_first_ipv6_gateway() {
 98 |     # debian 11 initrd 没有 xargs awk
 99 |     # debian 12 initrd 没有 xargs
100 |     if false; then
101 |         ip -6 route show default dev "$ethx" | head -1 | awk '{print $3}'
102 |     else
103 |         ip -6 route show default dev "$ethx" | head -1 | cut -d' ' -f3
104 |     fi
105 | }
106 | 
107 | is_have_ipv4_addr() {
108 |     ip -4 addr show scope global dev "$ethx" | grep -q inet
109 | }
110 | 
111 | is_have_ipv6_addr() {
112 |     ip -6 addr show scope global dev "$ethx" | grep -q inet6
113 | }
114 | 
115 | is_have_ipv4_gateway() {
116 |     ip -4 route show default dev "$ethx" | grep -q .
117 | }
118 | 
119 | is_have_ipv6_gateway() {
120 |     ip -6 route show default dev "$ethx" | grep -q .
121 | }
122 | 
123 | is_have_ipv4() {
124 |     is_have_ipv4_addr && is_have_ipv4_gateway
125 | }
126 | 
127 | is_have_ipv6() {
128 |     is_have_ipv6_addr && is_have_ipv6_gateway
129 | }
130 | 
131 | is_have_ipv4_dns() {
132 |     [ -f /etc/resolv.conf ] && grep -q '^nameserver .*\.' /etc/resolv.conf
133 | }
134 | 
135 | is_have_ipv6_dns() {
136 |     [ -f /etc/resolv.conf ] && grep -q '^nameserver .*:' /etc/resolv.conf
137 | }
138 | 
139 | add_missing_ipv4_config() {
140 |     if [ -n "$ipv4_addr" ] && [ -n "$ipv4_gateway" ]; then
141 |         if ! is_have_ipv4_addr; then
142 |             ip -4 addr add "$ipv4_addr" dev "$ethx"
143 |         fi
144 | 
145 |         if ! is_have_ipv4_gateway; then
146 |             # 如果 dhcp 无法设置onlink网关,那么在这里设置
147 |             # debian 9 ipv6 不能识别 onlink,但 ipv4 能识别 onlink
148 |             if true; then
149 |                 ip -4 route add "$ipv4_gateway" dev "$ethx"
150 |                 ip -4 route add default via "$ipv4_gateway" dev "$ethx"
151 |             else
152 |                 ip -4 route add default via "$ipv4_gateway" dev "$ethx" onlink
153 |             fi
154 |         fi
155 |     fi
156 | }
157 | 
158 | add_missing_ipv6_config() {
159 |     if [ -n "$ipv6_addr" ] && [ -n "$ipv6_gateway" ]; then
160 |         if ! is_have_ipv6_addr; then
161 |             ip -6 addr add "$ipv6_addr" dev "$ethx"
162 |         fi
163 | 
164 |         if ! is_have_ipv6_gateway; then
165 |             # 如果 dhcp 无法设置onlink网关,那么在这里设置
166 |             # debian 9 ipv6 不能识别 onlink
167 |             if true; then
168 |                 ip -6 route add "$ipv6_gateway" dev "$ethx"
169 |                 ip -6 route add default via "$ipv6_gateway" dev "$ethx"
170 |             else
171 |                 ip -6 route add default via "$ipv6_gateway" dev "$ethx" onlink
172 |             fi
173 |         fi
174 |     fi
175 | }
176 | 
177 | is_need_test_ipv4() {
178 |     is_have_ipv4 && ! $ipv4_has_internet
179 | }
180 | 
181 | is_need_test_ipv6() {
182 |     is_have_ipv6 && ! $ipv6_has_internet
183 | }
184 | 
185 | # 测试方法:
186 | # ping   有的机器禁止
187 | # nc     测试 dot doh 端口是否开启
188 | # wget   测试下载
189 | 
190 | # initrd 里面的软件版本,是否支持指定源IP/网卡
191 | # 软件     nc  wget  nslookup
192 | # debian9  ×    √   没有此软件
193 | # alpine   √    ×      ×
194 | 
195 | test_by_wget() {
196 |     src=$1
197 |     dst=$2
198 | 
199 |     # ipv6 需要添加 []
200 |     if echo "$dst" | grep -q ':'; then
201 |         url="https://[$dst]"
202 |     else
203 |         url="https://$dst"
204 |     fi
205 | 
206 |     # tcp 443 通了就算成功,不管 http 是不是 404
207 |     # grep -m1 快速返回
208 |     wget -T "$TEST_TIMEOUT" \
209 |         --bind-address="$src" \
210 |         --no-check-certificate \
211 |         --max-redirect 0 \
212 |         --tries 1 \
213 |         -O /dev/null \
214 |         "$url" 2>&1 | grep -iq -m1 connected
215 | }
216 | 
217 | test_by_nc() {
218 |     src=$1
219 |     dst=$2
220 | 
221 |     # tcp 443 通了就算成功
222 |     nc -z -v \
223 |         -w "$TEST_TIMEOUT" \
224 |         -s "$src" \
225 |         "$dst" 443
226 | }
227 | 
228 | is_debian_kali() {
229 |     [ -f /etc/lsb-release ] && grep -Eiq 'Debian|Kali' /etc/lsb-release
230 | }
231 | 
232 | test_connect() {
233 |     if is_debian_kali; then
234 |         test_by_wget "$1" "$2"
235 |     else
236 |         test_by_nc "$1" "$2"
237 |     fi
238 | }
239 | 
240 | test_internet() {
241 |     for i in $(seq 5); do
242 |         echo "Testing Internet Connection. Test $i... "
243 |         if is_need_test_ipv4 && { local current_ipv4_addr; current_ipv4_addr="$(get_first_ipv4_addr | remove_netmask)"; test_connect "$current_ipv4_addr" "$ipv4_dns1" >/dev/null 2>&1 || test_connect "$current_ipv4_addr" "$ipv4_dns2" >/dev/null 2>&1; }; then
244 |             echo "IPv4 has internet."
245 |             ipv4_has_internet=true
246 |         fi
247 |         if is_need_test_ipv6 && { local current_ipv6_addr; current_ipv6_addr="$(get_first_ipv6_addr | remove_netmask)"; test_connect "$current_ipv6_addr" "$ipv6_dns1" >/dev/null 2>&1 || test_connect "$current_ipv6_addr" "$ipv6_dns2" >/dev/null 2>&1; }; then
248 |             echo "IPv6 has internet."
249 |             ipv6_has_internet=true
250 |         fi
251 |         if ! is_need_test_ipv4 && ! is_need_test_ipv6; then
252 |             break
253 |         fi
254 |         sleep 1
255 |     done
256 | }
257 | 
258 | flush_ipv4_config() {
259 |     ip -4 addr flush scope global dev "$ethx"
260 |     ip -4 route flush dev "$ethx"
261 |     # DHCP 获取的 IP 不是重装前的 IP 时,一并删除 DHCP 获取的 DNS,以防 DNS 无效
262 |     sed -i "/\./d" /etc/resolv.conf
263 | }
264 | 
265 | should_disable_dhcpv4=false
266 | should_disable_accept_ra=false
267 | should_disable_autoconf=false
268 | 
269 | flush_ipv6_config() {
270 |     if $should_disable_accept_ra; then
271 |         echo 0 >"/proc/sys/net/ipv6/conf/$ethx/accept_ra"
272 |     fi
273 |     if $should_disable_autoconf; then
274 |         echo 0 >"/proc/sys/net/ipv6/conf/$ethx/autoconf"
275 |     fi
276 |     ip -6 addr flush scope global dev "$ethx"
277 |     ip -6 route flush dev "$ethx"
278 |     # DHCP 获取的 IP 不是重装前的 IP 时,一并删除 DHCP 获取的 DNS,以防 DNS 无效
279 |     sed -i "/:/d" /etc/resolv.conf
280 | }
281 | 
282 | for i in $(seq 20); do
283 |     if ethx=$(get_ethx); then
284 |         break
285 |     fi
286 |     sleep 1
287 | done
288 | 
289 | if [ -z "$ethx" ]; then
290 |     echo "Not found network card: $mac_addr"
291 |     exit
292 | fi
293 | 
294 | echo "Configuring $ethx ($mac_addr)..."
295 | 
296 | # 不开启 lo 则 frp 无法连接 127.0.0.1 22
297 | ip link set dev lo up
298 | 
299 | # 开启 ethx
300 | ip link set dev "$ethx" up
301 | sleep 1
302 | 
303 | # 开启 dhcpv4/v6
304 | # debian / kali
305 | if [ -f /usr/share/debconf/confmodule ]; then
306 |     # shellcheck source=/dev/null
307 |     . /usr/share/debconf/confmodule
308 | 
309 |     db_progress STEP 1
310 | 
311 |     # dhcpv4
312 |     # 无需等待写入 dns,在 dhcpv6 等待
313 |     db_progress INFO netcfg/dhcp_progress
314 |     udhcpc -i "$ethx" -f -q -n || true
315 |     db_progress STEP 1
316 | 
317 |     # slaac + dhcpv6
318 |     db_progress INFO netcfg/slaac_wait_title
319 |     # https://salsa.debian.org/installer-team/netcfg/-/blob/master/autoconfig.c#L148
320 |     cat <<EOF >/var/lib/netcfg/dhcp6c.conf
321 | interface $ethx {
322 |     send ia-na 0;
323 |     request domain-name-servers;
324 |     request domain-name;
325 |     script "/lib/netcfg/print-dhcp6c-info";
326 | };
327 | 
328 | id-assoc na 0 {
329 | };
330 | EOF
331 |     dhcp6c -c /var/lib/netcfg/dhcp6c.conf "$ethx" || true
332 |     sleep $DHCP_TIMEOUT # 等待获取 ip 和写入 dns
333 |     # kill-all-dhcp
334 |     kill -9 "$(cat /var/run/dhcp6c.pid)" || true
335 |     db_progress STEP 1
336 | 
337 |     # 静态 + 检测网络提示
338 |     db_subst netcfg/link_detect_progress interface "$ethx"
339 |     db_progress INFO netcfg/link_detect_progress
340 | else
341 |     # alpine
342 |     # h3c 移动云电脑使用 udhcpc 会重复提示 sending select,无法获得 ipv6,因此使用 dhcpcd
343 |     method=dhcpcd
344 | 
345 |     case "$method" in
346 |     udhcpc)
347 |         udhcpc -i "$ethx" -f -q -n || true
348 |         udhcpc6 -i "$ethx" -f -q -n || true
349 |         sleep $DNS_FILE_TIMEOUT # 好像不用等待写入 dns,但是以防万一
350 |         ;;
351 |     dhcpcd)
352 |         # https://gitlab.alpinelinux.org/alpine/aports/-/blob/master/main/dhcpcd/dhcpcd.pre-install
353 |         grep -q dhcpcd /etc/group || addgroup -S dhcpcd
354 |         grep -q dhcpcd /etc/passwd || adduser -S -D -H \
355 |             -h /var/lib/dhcpcd \
356 |             -s /sbin/nologin \
357 |             -G dhcpcd \
358 |             -g dhcpcd \
359 |             dhcpcd
360 | 
361 |         # --noipv4ll 禁止生成 169.254.x.x
362 |         if false; then
363 |             # 等待 DHCP 全过程
364 |             timeout $DHCP_TIMEOUT \
365 |                 dhcpcd --persistent --noipv4ll --nobackground "$ethx"
366 |         else
367 |             # 等待 DNS
368 |             dhcpcd --persistent --noipv4ll "$ethx" # 获取到 IP 后立即切换到后台
369 |             sleep $DNS_FILE_TIMEOUT                # 需要等待写入 dns
370 |             dhcpcd -x "$ethx"                      # 终止
371 |         fi
372 |         ;;
373 |     esac
374 | fi
375 | 
376 | # 等待slaac
377 | # 有ipv6地址就跳过,不管是slaac或者dhcpv6
378 | # 因为会在trans里判断
379 | # 这里等待5秒就够了,因为之前尝试获取dhcp6也用了一段时间
380 | for i in $(seq 5 -1 0); do
381 |     is_have_ipv6 && break
382 |     echo "waiting slaac for ${i}s"
383 |     sleep 1
384 | done
385 | 
386 | # 记录是否有动态地址
387 | # 由于还没设置静态ip,所以有条目表示有动态地址
388 | is_have_ipv4_addr && dhcpv4=true || dhcpv4=false
389 | is_have_ipv6_addr && dhcpv6_or_slaac=true || dhcpv6_or_slaac=false
390 | is_have_ipv6_gateway && ra_has_gateway=true || ra_has_gateway=false
391 | 
392 | # 如果自动获取的 IP 不是重装前的,则改成静态,使用之前的 IP
393 | # 只比较 IP,不比较掩码/网关,因为
394 | # 1. 假设掩码/网关导致无法上网,后面也会检测到并改成静态
395 | # 2. openSUSE wicked dhcpv6 是 64 位掩码,aws lightsail 模板上的也是,而其它 dhcpv6 软件都是 128 位掩码
396 | if $dhcpv4 && [ -n "$ipv4_addr" ] && [ -n "$ipv4_gateway" ] &&
397 |     ! [ "$(echo "$ipv4_addr" | cut -d/ -f1)" = "$(get_first_ipv4_addr | cut -d/ -f1)" ]; then
398 |     echo "IPv4 address obtained from DHCP is different from old system."
399 |     should_disable_dhcpv4=true
400 |     flush_ipv4_config
401 | fi
402 | if $dhcpv6_or_slaac && [ -n "$ipv6_addr" ] && [ -n "$ipv6_gateway" ] &&
403 |     ! [ "$(echo "$ipv6_addr" | cut -d/ -f1)" = "$(get_first_ipv6_addr | cut -d/ -f1)" ]; then
404 |     echo "IPv6 address obtained from SLAAC/DHCPv6 is different from old system."
405 |     should_disable_accept_ra=true
406 |     should_disable_autoconf=true
407 |     flush_ipv6_config
408 | fi
409 | 
410 | # 设置静态地址,或者设置 debian 9 udhcpc 无法设置的网关
411 | add_missing_ipv4_config
412 | add_missing_ipv6_config
413 | 
414 | # 检查 ipv4/ipv6 是否连接联网
415 | ipv4_has_internet=false
416 | ipv6_has_internet=false
417 | test_internet
418 | 
419 | # 如果无法上网,并且自动获取的 掩码/网关 不是重装前的,则改成静态
420 | # ip_addr 包括 IP/掩码,所以可以用来判断掩码是否不同
421 | # IP 不同的情况在前面已经改成静态了
422 | if ! $ipv4_has_internet &&
423 |     $dhcpv4 && [ -n "$ipv4_addr" ] && [ -n "$ipv4_gateway" ] &&
424 |     ! { [ "$ipv4_addr" = "$(get_first_ipv4_addr)" ] && [ "$ipv4_gateway" = "$(get_first_ipv4_gateway)" ]; }; then
425 |     echo "IPv4 netmask/gateway obtained from DHCP is different from old system."
426 |     should_disable_dhcpv4=true
427 |     flush_ipv4_config
428 |     add_missing_ipv4_config
429 |     test_internet
430 | fi
431 | # 有可能是静态 IPv6 但能从 RA 获取到网关,因此加上 || $ra_has_gateway
432 | if ! $ipv6_has_internet &&
433 |     { $dhcpv6_or_slaac || $ra_has_gateway; } &&
434 |     [ -n "$ipv6_addr" ] && [ -n "$ipv6_gateway" ] &&
435 |     ! { [ "$ipv6_addr" = "$(get_first_ipv6_addr)" ] && [ "$ipv6_gateway" = "$(get_first_ipv6_gateway)" ]; }; then
436 |     echo "IPv6 netmask/gateway obtained from SLAAC/DHCPv6 is different from old system."
437 |     should_disable_accept_ra=true
438 |     should_disable_autoconf=true
439 |     flush_ipv6_config
440 |     add_missing_ipv6_config
441 |     test_internet
442 | fi
443 | 
444 | # 要删除不联网协议的ip,因为
445 | # 1 甲骨文云管理面板添加ipv6地址然后取消
446 | #   依然会分配ipv6地址,但ipv6没网络
447 | #   此时alpine只会用ipv6下载apk,而不用会ipv4下载
448 | # 2 有ipv4地址但没有ipv4网关的情况(vultr $2.5 ipv6 only),aria2会用ipv4下载
449 | 
450 | # 假设 ipv4 ipv6 在不同网卡,ipv4 能上网但 ipv6 不能上网,这时也要删除 ipv6
451 | # 不能用 ipv4_has_internet && ! ipv6_has_internet 判断,因为它判断的是同一个网卡
452 | if ! $ipv4_has_internet; then
453 |     if $dhcpv4; then
454 |         should_disable_dhcpv4=true
455 |     fi
456 |     flush_ipv4_config
457 | fi
458 | if ! $ipv6_has_internet; then
459 |     # 防止删除 IPv6 后再次通过 SLAAC 获得
460 |     # 不用判断 || $ra_has_gateway ,因为没有 IPv6 地址但有 IPv6 网关时,不会出现下载问题
461 |     if $dhcpv6_or_slaac; then
462 |         should_disable_accept_ra=true
463 |         should_disable_autoconf=true
464 |     fi
465 |     flush_ipv6_config
466 | fi
467 | 
468 | # 如果联网了,但没获取到默认 DNS,则添加我们的 DNS
469 | 
470 | # 有一种情况是,多网卡,且能上网的网卡先完成了这个脚本,不能上网的网卡后完成
471 | # 无法上网的网卡通过 flush_ipv4_config 删除了不能上网的 IP 和 dns
472 | # (原计划是删除无法上网的网卡 dhcp4 获取的 dns,但实际上无法区分)
473 | # 因此这里直接添加 dns,不判断是否联网
474 | if ! is_have_ipv4_dns; then
475 |     echo "nameserver $ipv4_dns1" >>/etc/resolv.conf
476 |     echo "nameserver $ipv4_dns2" >>/etc/resolv.conf
477 | fi
478 | if ! is_have_ipv6_dns; then
479 |     echo "nameserver $ipv6_dns1" >>/etc/resolv.conf
480 |     echo "nameserver $ipv6_dns2" >>/etc/resolv.conf
481 | fi
482 | 
483 | # 传参给 trans.start
484 | netconf="/dev/netconf/$ethx"
485 | mkdir -p "$netconf"
486 | $dhcpv4 && echo 1 >"$netconf/dhcpv4" || echo 0 >"$netconf/dhcpv4"
487 | $dhcpv6_or_slaac && echo 1 >"$netconf/dhcpv6_or_slaac" || echo 0 >"$netconf/dhcpv6_or_slaac"
488 | $should_disable_dhcpv4 && echo 1 >"$netconf/should_disable_dhcpv4" || echo 0 >"$netconf/should_disable_dhcpv4"
489 | $should_disable_accept_ra && echo 1 >"$netconf/should_disable_accept_ra" || echo 0 >"$netconf/should_disable_accept_ra"
490 | $should_disable_autoconf && echo 1 >"$netconf/should_disable_autoconf" || echo 0 >"$netconf/should_disable_autoconf"
491 | $is_in_china && echo 1 >"$netconf/is_in_china" || echo 0 >"$netconf/is_in_china"
492 | echo "$ethx" >"$netconf/ethx"
493 | echo "$mac_addr" >"$netconf/mac_addr"
494 | echo "$ipv4_addr" >"$netconf/ipv4_addr"
495 | echo "$ipv4_gateway" >"$netconf/ipv4_gateway"
496 | echo "$ipv6_addr" >"$netconf/ipv6_addr"
497 | echo "$ipv6_gateway" >"$netconf/ipv6_gateway"
498 | $ipv4_has_internet && echo 1 >"$netconf/ipv4_has_internet" || echo 0 >"$netconf/ipv4_has_internet"
499 | $ipv6_has_internet && echo 1 >"$netconf/ipv6_has_internet" || echo 0 >"$netconf/ipv6_has_internet"
500 | 


--------------------------------------------------------------------------------
/logviewer-nginx.conf:
--------------------------------------------------------------------------------
 1 | server {
 2 |     listen @WEB_PORT@;
 3 |     listen [::]:@WEB_PORT@;
 4 |     root /;
 5 | 
 6 |     gzip on;
 7 |     gzip_types text/plain;
 8 | 
 9 | 
10 |     location = / {
11 |         try_files /logviewer.html 404;
12 |     }
13 | 
14 |     location = /reinstall.log {
15 |         types {
16 |             text/plain log;
17 |         }
18 | 
19 |         try_files $uri 404;
20 |     }
21 | 
22 |     location / {
23 |         return 404;
24 |     }
25 | }


--------------------------------------------------------------------------------
/logviewer.html:
--------------------------------------------------------------------------------
  1 | <!DOCTYPE html>
  2 | <html>
  3 | 
  4 | <head>
  5 |     <title>Reinstall Logs</title>
  6 |     <style>
  7 |         body {
  8 |             margin: 0;
  9 |             padding: 0;
 10 |             overflow: hidden;
 11 |         }
 12 | 
 13 |         #log-container {
 14 |             height: calc(100vh);
 15 |             margin: 0;
 16 |             padding: 8px;
 17 |             overflow-y: scroll;
 18 |         }
 19 | 
 20 |         #scroll-to-bottom {
 21 |             position: fixed;
 22 |             bottom: 24px;
 23 |             right: 24px;
 24 |             background-color: #0099FF;
 25 |             color: #fff;
 26 |             border: none;
 27 |             cursor: pointer;
 28 |             display: none;
 29 |             width: 48px;
 30 |             height: 48px;
 31 |             border-radius: 50%;
 32 |         }
 33 | 
 34 |         #scroll-to-bottom:hover {
 35 |             background-color: #00CCFF;
 36 |         }
 37 | 
 38 |         #scroll-to-bottom svg {
 39 |             fill: #fff;
 40 |         }
 41 | 
 42 |         .done {
 43 |             background-color: #cfc;
 44 |         }
 45 | 
 46 |         .error {
 47 |             background-color: #fcc;
 48 |         }
 49 |     </style>
 50 | </head>
 51 | 
 52 | <body>
 53 |     <pre id="log-container"></pre>
 54 |     <button id="scroll-to-bottom">
 55 |         <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
 56 |             <path d="M5 10l7 7 7-7H5z" />
 57 |         </svg>
 58 |     </button>
 59 | 
 60 |     <script
 61 |         src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-d/reconnecting-websocket/1.0.0/reconnecting-websocket.min.js"
 62 |         type="application/javascript"></script>
 63 | 
 64 |     <script>
 65 |         const logContainer = document.getElementById('log-container');
 66 |         const scrollToBottomButton = document.getElementById('scroll-to-bottom');
 67 |         let shouldScrollToBottom = true;
 68 | 
 69 |         scrollToBottomButton.addEventListener('click', () => {
 70 |             logContainer.scrollTop = logContainer.scrollHeight;
 71 |         });
 72 | 
 73 |         logContainer.addEventListener('scroll', () => {
 74 |             const isAtBottom = Math.ceil(logContainer.scrollTop + logContainer.clientHeight) >= logContainer.scrollHeight;
 75 |             if (isAtBottom) {
 76 |                 scrollToBottomButton.style.display = 'none';
 77 |             } else {
 78 |                 scrollToBottomButton.style.display = 'block';
 79 |             }
 80 | 
 81 |             shouldScrollToBottom = isAtBottom;
 82 |         });
 83 | 
 84 |         var ws = new ReconnectingWebSocket('ws://' + location.host + '/');
 85 |         ws.onopen = function () {
 86 |             logContainer.textContent += '\nWebSocket Connected.';
 87 |         };
 88 |         ws.onclose = function () {
 89 |             logContainer.textContent += '\nWebSocket Disconnected.';
 90 |         };
 91 |         ws.onmessage = function (event) {
 92 |             logContainer.textContent += '\n' + event.data;
 93 |             if (shouldScrollToBottom) {
 94 |                 logContainer.scrollTop = logContainer.scrollHeight;
 95 |             }
 96 |             // 开始/重新开始
 97 |             if (event.data.includes('***** START TRANS *****')) {
 98 |                 document.body.className = ''
 99 |             }
100 |             // 错误
101 |             else if (event.data.includes('***** ERROR *****')) {
102 |                 document.body.className = 'error'
103 |             }
104 |             // 完成
105 |             else if (event.data.includes('***** DONE *****')) {
106 |                 document.body.className = 'done'
107 |             }
108 |         };
109 |     </script>
110 | </body>
111 | 
112 | </html>
113 | 


--------------------------------------------------------------------------------
/redhat.cfg:
--------------------------------------------------------------------------------
  1 | # shellcheck disable=SC2148
  2 | # 设置
  3 | keyboard --vckeymap=us --xlayouts='us'
  4 | lang en_US.UTF-8
  5 | timezone Asia/Shanghai --utc
  6 | rootpw --plaintext 123@@@
  7 | text
  8 | reboot
  9 | %include /tmp/include-url-command
 10 | 
 11 | # 分区
 12 | %include /tmp/include-disk-only-use
 13 | %include /tmp/include-bootloader
 14 | clearpart --all --initlabel
 15 | reqpart # 如果需要,自动创建 efi 或 biosboot 分区
 16 | part / --fstype=xfs --grow
 17 | 
 18 | # 软件
 19 | %packages --ignoremissing # el9 minimal.iso fedora Server repo/iso 没有 tuned
 20 | @^Minimal Install
 21 | %include /tmp/include-packages-for-resize
 22 | %include /tmp/exclude-packages-for-vm
 23 | %end
 24 | 
 25 | # 禁用防火墙
 26 | # firewall --disabled
 27 | 
 28 | # 禁用 selinux
 29 | selinux --disabled
 30 | 
 31 | # 禁用 kdump
 32 | %addon com_redhat_kdump --disable
 33 | %end
 34 | 
 35 | ##############################################
 36 | %pre
 37 | distro=$(awk -F: '{ print $3 }' </etc/system-release-cpe)
 38 | releasever=$(awk -F: '{ print $5 }' </etc/system-release-cpe)
 39 | 
 40 | # 重新整理 extra,grub把两侧的引号吃掉了,eval出错,要重新添加引号
 41 | # 提取 extra_confhome extra_mirrorlist extra_main_disk
 42 | prefix=extra
 43 | for var in $(grep -o "\b${prefix}_[^ ]*" /proc/cmdline | xargs); do
 44 |     eval "$(echo "$var" | sed -E "s/${prefix}_([^=]*)=(.*)/\1='\2'/")"
 45 | done
 46 | 
 47 | # centos7 证书链未更新,需要 --no-check-certificate
 48 | 
 49 | # 只使用主硬盘
 50 | include=/tmp/include-disk-only-use
 51 | xda=$(wget --no-check-certificate --tries=5 "$confhome/get-xda.sh" -O- | sh -s)
 52 | echo "ignoredisk --only-use=$xda" >$include
 53 | 
 54 | # 设置 tty
 55 | include=/tmp/include-bootloader
 56 | # shellcheck disable=SC2154
 57 | console_cmdline=$(wget --no-check-certificate --tries=5 "$confhome/ttys.sh" -O- | sh -s console=)
 58 | echo "bootloader --append=\"$console_cmdline\"" >$include
 59 | 
 60 | # 有 installer 分区,表示用了两步安装
 61 | include=/tmp/include-packages-for-resize
 62 | touch $include
 63 | if [ -e /dev/disk/by-label/installer ]; then
 64 |     # 1g内存下,安装器默认开启了zram ,但安装f38还是不够内存
 65 |     # 具体表现为不断重启安装界面,所以还要开启swap
 66 |     ram_size=$(lsmem -b 2>/dev/null | grep 'Total online memory:' | awk '{ print $NF/1024/1024 }')
 67 |     if [ -z "$ram_size" ] || [ "$ram_size" -le 1024 ]; then
 68 |         mount /dev/disk/by-label/installer /run/install/repo -o remount,rw
 69 |         swapfile=/run/install/repo/swapfile
 70 |         if command -v fallocate; then
 71 |             fallocate -l 1G $swapfile
 72 |         else
 73 |             dd if=/dev/zero of=$swapfile bs=1M count=1024
 74 |         fi
 75 |         chmod 0600 $swapfile
 76 |         mkswap $swapfile
 77 |         swapon $swapfile
 78 |     fi
 79 | 
 80 |     # feroda 默认不包含 cronie
 81 |     echo cronie >>$include
 82 | 
 83 |     # el7 的parted不支持在线扩容,要用 growpart 和 gdisk 处理 gpt 分区
 84 |     if [ "$releasever" = "7" ]; then
 85 |         echo cloud-utils-growpart >>$include
 86 |         echo gdisk >>$include
 87 |     fi
 88 | fi
 89 | 
 90 | # 排除虚拟机用不上的组件
 91 | include=/tmp/exclude-packages-for-vm
 92 | touch $include
 93 | if systemd-detect-virt -v; then
 94 |     cat <<EOF >$include
 95 |         # 不删除usb相关的包 因为甲骨文云有usb设备 作用未知
 96 |         # -usb_modeswitch
 97 |         # -usbutils
 98 | 
 99 |         # 无线
100 |         -iw
101 |         -crda
102 |         -rfkill
103 |         -iwl*-firmware
104 | 
105 |         # 其他
106 |         -irqbalance # 多核+直通设备可能有用?
107 |         -microcode_ctl
108 |         -smartmontools
109 | 
110 |         # 各种固件
111 |         -aic94xx-firmware
112 |         -alsa-firmware
113 |         -ivtv-firmware
114 |         # -linux-firmware # 去除后安装centos 8会报错
115 | 
116 |         # fedora 特有固件
117 |         -amd-gpu-firmware
118 |         -atheros-firmware
119 |         -brcmfmac-firmware
120 |         -intel-gpu-firmware
121 |         -mt7xxx-firmware
122 |         -nvidia-gpu-firmware
123 |         -realtek-firmware
124 | EOF
125 | fi
126 | 
127 | # 设置安装源
128 | include=/tmp/include-url-command
129 | # shellcheck disable=SC2154
130 | if [ "$localtest" = 1 ]; then
131 |     echo "url --url=$confhome/$releasever/" >$include
132 |     # echo cdrom >$include
133 | else
134 |     echo "url --mirrorlist=$mirrorlist" >$include
135 |     # 对于el7/fedora, 添加了 updates repo 才会安装最新的包
136 |     if [ "$releasever" = "7" ] || [ "$distro" = "fedoraproject" ]; then
137 |         echo "repo --name=updates" >>$include
138 |     fi
139 | fi
140 | %end
141 | 
142 | ##############################################
143 | %post
144 | # el9/fedora的sshd默认不允许root密码登录,需手动开启
145 | # rootpw --allow-ssh 9.1 以上才支持
146 | distro=$(awk -F: '{ print $3 }' </etc/system-release-cpe)
147 | releasever=$(awk -F: '{ print $5 }' </etc/system-release-cpe)
148 | if [ "$releasever" = "9" ] || [ "$distro" = "fedoraproject" ]; then
149 |     echo "PermitRootLogin yes" >/etc/ssh/sshd_config.d/01-permitrootlogin.conf
150 | fi
151 | 
152 | # 分步安装的系统,要将最后一个分区(installer)合并到系统分区
153 | if [ -e /dev/disk/by-label/installer ]; then
154 |     # 提取 extra_localtest extra_confhome extra_mirrorlist
155 |     prefix=extra
156 |     for var in $(grep -o "\b${prefix}_[^ ]*" /proc/cmdline | xargs); do
157 |         eval "$(echo "$var" | sed -E "s/${prefix}_([^=]*)=(.*)/\1='\2'/")"
158 |     done
159 | 
160 |     cd /
161 |     curl -O "$confhome/resize.sh"
162 |     echo '@reboot root bash /resize.sh' >/etc/cron.d/resize
163 | fi
164 | %end
165 | 


--------------------------------------------------------------------------------
/reinstall.bat:
--------------------------------------------------------------------------------
  1 | @echo off
  2 | mode con cp select=437 >nul
  3 | setlocal EnableDelayedExpansion
  4 | 
  5 | set confhome=https://raw.githubusercontent.com/bin456789/reinstall/main
  6 | set confhome_cn=https://cnb.cool/bin456789/reinstall/-/git/raw/main
  7 | rem set confhome_cn=https://www.ghproxy.cc/https://raw.githubusercontent.com/bin456789/reinstall/main
  8 | 
  9 | set pkgs=curl,cpio,p7zip,dos2unix,jq,xz,gzip,zstd,openssl,bind-utils,libiconv,binutils
 10 | set cmds=curl,cpio,p7zip,dos2unix,jq,xz,gzip,zstd,openssl,nslookup,iconv,ar
 11 | 
 12 | rem 65001 代码页会乱码
 13 | 
 14 | rem 不要用 :: 注释
 15 | rem 否则可能会出现 系统找不到指定的驱动器
 16 | 
 17 | rem Windows 7 SP1 winhttp 默认不支持 tls 1.2
 18 | rem https://support.microsoft.com/en-us/topic/update-to-enable-tls-1-1-and-tls-1-2-as-default-secure-protocols-in-winhttp-in-windows-c4bd73d2-31d7-761e-0178-11268bb10392
 19 | rem 有些系统根证书没更新
 20 | rem 所以不要用https
 21 | rem 进入脚本目录
 22 | cd /d %~dp0
 23 | 
 24 | rem 检查是否有管理员权限
 25 | fltmc >nul 2>&1
 26 | if errorlevel 1 (
 27 |     echo Please run as administrator^^!
 28 |     exit /b
 29 | )
 30 | 
 31 | rem 有时 %tmp% 带会话 id,且文件夹不存在
 32 | rem https://learn.microsoft.com/troubleshoot/windows-server/shell-experience/temp-folder-with-logon-session-id-deleted
 33 | rem if not exist %tmp% (
 34 | rem     md %tmp%
 35 | rem )
 36 | 
 37 | rem 下载 geoip
 38 | if not exist geoip (
 39 |     rem www.cloudflare.com/dash.cloudflare.com 国内访问的是美国服务器,而且部分地区被墙
 40 |     call :download http://www.qualcomm.cn/cdn-cgi/trace %~dp0geoip || goto :download_failed
 41 | )
 42 | 
 43 | rem 判断是否有 loc=
 44 | findstr /c:"loc=" geoip >nul
 45 | if errorlevel 1 (
 46 |     echo Invalid geoip file
 47 |     del geoip
 48 |     exit /b 1
 49 | )
 50 | 
 51 | rem 检查是否国内
 52 | findstr /c:"loc=CN" geoip >nul
 53 | if not errorlevel 1 (
 54 |     rem mirrors.tuna.tsinghua.edu.cn 会强制跳转 https
 55 |     set mirror=http://mirror.nju.edu.cn
 56 |     if defined confhome_cn (
 57 |         set confhome=!confhome_cn!
 58 |     ) else if defined github_proxy (
 59 |         echo !confhome! | findstr /c:"://raw.githubusercontent.com/" >nul
 60 |         if not errorlevel 1 (
 61 |             set confhome=!confhome:http://=https://!
 62 |             set confhome=!confhome:https://raw.githubusercontent.com=%github_proxy%!
 63 |         )
 64 |     )
 65 | ) else (
 66 |     rem 服务器在美国 equinix 机房,不是 cdn
 67 |     set mirror=http://mirrors.kernel.org
 68 | )
 69 | 
 70 | call :check_cygwin_installed || (
 71 |     rem win10 arm 支持运行 x86 软件
 72 |     rem win11 arm 支持运行 x86 和 x86_64 软件
 73 | 
 74 |     rem windows 11 24h2 没有 wmic
 75 |     rem wmic os get osarchitecture 显示中文,即使设置了 mode con cp select=437
 76 |     rem wmic ComputerSystem get SystemType 显示英文
 77 |     rem for /f "tokens=*" %%a in ('wmic ComputerSystem get SystemType ^| find /i "based"') do (
 78 |     rem     set "SystemType=%%a"
 79 |     rem )
 80 | 
 81 |     rem 有的系统精简了 powershell
 82 |     rem for /f "delims=" %%a in ('powershell -NoLogo -NoProfile -NonInteractive -Command "(Get-WmiObject win32_computersystem).SystemType"') do (
 83 |     rem     set "SystemType=%%a"
 84 |     rem )
 85 | 
 86 |     rem SystemArch
 87 |     for /f "tokens=3" %%a in ('reg query "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v PROCESSOR_ARCHITECTURE') do (
 88 |         set SystemArch=%%a
 89 |     )
 90 | 
 91 |     rem 也可以用 PROCESSOR_ARCHITEW6432 和 PROCESSOR_ARCHITECTURE 判断
 92 |     rem ARM64 win11  PROCESSOR_ARCHITEW6432   PROCESSOR_ARCHITECTURE
 93 |     rem 原生cmd          未定义                      ARM64
 94 |     rem 32位cmd          ARM64                       x86
 95 | 
 96 |     rem if defined PROCESSOR_ARCHITEW6432 (
 97 |     rem     set "SystemArch=%PROCESSOR_ARCHITEW6432%"
 98 |     rem ) else (
 99 |     rem     set "SystemArch=%PROCESSOR_ARCHITECTURE%"
100 |     rem )
101 | 
102 |     rem BuildNumber
103 |     for /f "tokens=3" %%a in ('reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /v CurrentBuildNumber') do (
104 |         set /a BuildNumber=%%a
105 |     )
106 | 
107 |     set CygwinEOL=1
108 | 
109 |     echo !SystemArch! | find "ARM" > nul
110 |     if not errorlevel 1 (
111 |         if !BuildNumber! GEQ 22000 (
112 |             set CygwinEOL=0
113 |         )
114 |     ) else (
115 |         echo !SystemArch! | find "AMD64" > nul
116 |         if not errorlevel 1 (
117 |             if !BuildNumber! GEQ 9600 (
118 |                 set CygwinEOL=0
119 |             )
120 |         )
121 |     )
122 | 
123 |     rem win7/8 cygwin 已 EOL,不能用最新 cygwin 源,而要用 Cygwin Time Machine 源
124 |     rem 但 Cygwin Time Machine 没有国内源
125 |     rem 为了保证国内下载速度, cygwin EOL 统一使用 cygwin-archive x86 源
126 |     if !CygwinEOL! == 1 (
127 |         set CygwinArch=x86
128 |         set dir=/sourceware/cygwin-archive/20221123
129 |     ) else (
130 |         set CygwinArch=x86_64
131 |         set dir=/sourceware/cygwin
132 |     )
133 | 
134 |     rem 下载 Cygwin
135 |     if not exist setup-!CygwinArch!.exe (
136 |         call :download http://www.cygwin.com/setup-!CygwinArch!.exe %~dp0setup-!CygwinArch!.exe || goto :download_failed
137 |     )
138 | 
139 |     rem 少于 1M 视为无效
140 |     rem 有的 IP 被官网拉黑,无法下载 exe,下载得到 html
141 |     for %%A in (setup-!CygwinArch!.exe) do if %%~zA LSS 1048576 (
142 |         echo Invalid Cgywin installer
143 |         del setup-!CygwinArch!.exe
144 |         exit /b 1
145 |     )
146 | 
147 |     rem 安装 Cygwin
148 |     set site=!mirror!!dir!
149 |     start /wait setup-!CygwinArch!.exe ^
150 |         --allow-unsupported-windows ^
151 |         --quiet-mode ^
152 |         --only-site ^
153 |         --site !site! ^
154 |         --root %SystemDrive%\cygwin ^
155 |         --local-package-dir %~dp0cygwin-local-package-dir ^
156 |         --packages %pkgs%
157 | 
158 |     rem 检查 Cygwin 是否成功安装
159 |     if errorlevel 1 goto :install_cygwin_failed
160 |     call :check_cygwin_installed || goto :install_cygwin_failed
161 | )
162 | 
163 | rem 在c盘根目录下执行 cygpath -ua . 会得到 /cygdrive/c,因此末尾要有 /
164 | for /f %%a in ('%SystemDrive%\cygwin\bin\cygpath -ua ./') do set thisdir=%%a
165 | 
166 | rem 下载 reinstall.sh
167 | if not exist reinstall.sh (
168 |     call :download_with_curl %confhome%/reinstall.sh %thisdir%reinstall.sh || goto :download_failed
169 |     call :chmod a+x %thisdir%reinstall.sh
170 | )
171 | 
172 | rem %* 无法处理 --iso https://x.com/?yyy=123
173 | rem 为每个参数添加引号,使参数正确传递到 bash
174 | rem for %%a in (%*) do (
175 | rem     set "param=!param! "%%~a""
176 | rem )
177 | 
178 | rem 转成 unix 格式,避免用户用 windows 记事本编辑后换行符不对
179 | %SystemDrive%\cygwin\bin\dos2unix -q '%thisdir%reinstall.sh'
180 | 
181 | rem 用 bash 运行
182 | rem %SystemDrive%\cygwin\bin\bash -l %thisdir%reinstall.sh %* 运行后会清屏
183 | rem 因此不能用 -l
184 | rem 这就需要在 reinstall.sh 里运行 source /etc/profile
185 | rem 或者添加 export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH
186 | %SystemDrive%\cygwin\bin\bash %thisdir%reinstall.sh %*
187 | exit /b
188 | 
189 | rem bits 要求有 Content-Length 才能下载
190 | rem cloudflare 的 cdn-cgi/trace 没有 Content-Length
191 | rem 据说如果网络设为“按流量计费” bits 也无法下载
192 | rem https://learn.microsoft.com/en-us/windows/win32/bits/http-requirements-for-bits-downloads
193 | rem bitsadmin /transfer "%~3" /priority foreground %~1 %~2
194 | 
195 | :download
196 | rem certutil 会被 windows Defender 报毒
197 | rem windows server 2019 要用第二条 certutil 命令
198 | echo Download: %~1 %~2
199 | del /q "%~2" 2>nul
200 | if exist "%~2" (echo Cannot delete %~2 & exit /b 1)
201 | 
202 | certutil -urlcache -f -split "%~1" "%~2" >nul
203 | if not errorlevel 1 if exist "%~2" exit /b 0
204 | 
205 | certutil -urlcache -split "%~1" "%~2" >nul
206 | if not errorlevel 1 if exist "%~2" exit /b 0
207 | 
208 | rem 下载失败时删除文件,防止下载了一部分导致下次运行时跳过了下载
209 | del /q "%~2" 2>nul
210 | exit /b 1
211 | 
212 | :download_with_curl
213 | rem 加 --insecure 防止以下错误
214 | rem curl: (77) error setting certificate verify locations:
215 | rem   CAfile: /etc/ssl/certs/ca-certificates.crt
216 | rem   CApath: none
217 | echo Download: %~1 %~2
218 | %SystemDrive%\cygwin\bin\curl -L --insecure "%~1" -o "%~2"
219 | exit /b
220 | 
221 | :chmod
222 | %SystemDrive%\cygwin\bin\chmod "%~1" "%~2"
223 | exit /b
224 | 
225 | :download_failed
226 | echo Download failed.
227 | exit /b 1
228 | 
229 | :install_cygwin_failed
230 | echo Failed to install Cygwin.
231 | exit /b 1
232 | 
233 | :check_cygwin_installed
234 | set "cmds_space=%cmds:,= %"
235 | for %%c in (%cmds_space%) do (
236 |     if not exist "%SystemDrive%\cygwin\bin\%%c" if not exist "%SystemDrive%\cygwin\bin\%%c.exe" (
237 |         exit /b 1
238 |     )
239 | )
240 | exit /b 0
241 | 


--------------------------------------------------------------------------------
/resize.sh:
--------------------------------------------------------------------------------
 1 | #!/bin/bash
 2 | PATH="/usr/sbin:/usr/bin"
 3 | 
 4 | update_part() {
 5 |     partx -u "$1"
 6 |     udevadm trigger
 7 |     udevadm settle
 8 | }
 9 | 
10 | # el 自带 fdisk parted (el7的part不支持在线扩容)
11 | # ubuntu 自带 fdisk growpart
12 | 
13 | # 删除分区用
14 | # el/ubuntu fdisk
15 | 
16 | # 扩容分区用
17 | # el7 grownparted 额外安装
18 | # el8/9/fedora parted
19 | # ubuntu grownpart
20 | 
21 | # 找出主硬盘
22 | root_drive=$(mount | awk '$3=="/" {print $1}')
23 | xda=$(lsblk -r --inverse "$root_drive" | grep -w disk | awk '{print $1}')
24 | 
25 | # 删除 installer 分区
26 | installer_num=$(readlink -f /dev/disk/by-label/installer | grep -o '[0-9]*
#39;)
27 | if [ -n "$installer_num" ]; then
28 |     # 要添加 LC_NUMERIC 或者将%转义成\%才能在cron里正确运行
29 |     # locale -a 不一定有"en_US.UTF-8",但肯定有"C.UTF-8"
30 |     LC_NUMERIC="C.UTF-8"
31 |     printf "d\n%s\nw" "$installer_num" | fdisk "/dev/$xda"
32 |     update_part "/dev/$xda"
33 | fi
34 | 
35 | # 找出现在的最后一个分区,也就是系统分区
36 | # el7 的 lsblk 没有 --sort,所以用其他方法
37 | # shellcheck disable=2012
38 | part_num=$(ls -1v "/dev/$xda"* | tail -1 | grep -o '[0-9]*
#39;)
39 | part_fstype=$(lsblk -no FSTYPE "/dev/$xda"*"$part_num")
40 | 
41 | # 扩容分区
42 | # ubuntu 和 el7 用 growpart,其他用 parted
43 | # el7 不能用parted在线扩容,而fdisk扩容会改变 PARTUUID,所以用 growpart
44 | if grep -E -i 'centos:7|ubuntu' /etc/os-release; then
45 |     growpart "/dev/$xda" "$part_num"
46 | else
47 |     printf 'yes\n100%%' | parted "/dev/$xda" resizepart "$part_num" ---pretend-input-tty
48 | fi
49 | update_part "/dev/$xda"
50 | 
51 | # 扩容最后一个分区的文件系统
52 | case $part_fstype in
53 | xfs) xfs_growfs / ;;
54 | ext*) resize2fs "/dev/$xda"*"$part_num" ;;
55 | btrfs) btrfs filesystem resize max / ;;
56 | esac
57 | update_part "/dev/$xda"
58 | 
59 | # 删除脚本自身
60 | rm -f /resize.sh /etc/cron.d/resize
61 | 


--------------------------------------------------------------------------------
/ttys.sh:
--------------------------------------------------------------------------------
 1 | #!/bin/sh
 2 | prefix=$1
 3 | 
 4 | # 不要在 windows 上使用,因为不准确
 5 | # 在原系统上使用,也可能不准确?例如安装了 cloud 内核的甲骨文?
 6 | 
 7 | # 注意 debian initrd 没有 xargs
 8 | 
 9 | # 最后一个 tty 是主 tty,显示的信息最全
10 | is_first=true
11 | if [ "$(uname -m)" = "aarch64" ]; then
12 |     ttys="ttyS0 ttyAMA0 tty0"
13 | else
14 |     ttys="ttyS0 tty0"
15 | fi
16 | 
17 | for tty in $ttys; do
18 |     # hytron 有ttyS0 但无法写入
19 |     if stty -g -F "/dev/$tty" >/dev/null 2>&1; then
20 |         if $is_first; then
21 |             is_first=false
22 |         else
23 |             printf " "
24 |         fi
25 | 
26 |         printf "%s" "$prefix$tty"
27 | 
28 |         if [ "$prefix" = "console=" ] &&
29 |             { [ "$tty" = ttyS0 ] || [ "$tty" = ttyAMA0 ]; }; then
30 |             printf ",115200n8"
31 |         fi
32 |     fi
33 | done
34 | 


--------------------------------------------------------------------------------
/ubuntu-storage-early.sh:
--------------------------------------------------------------------------------
  1 | #!/bin/bash
  2 | sed -i -E '/^\.{3}$/d' /autoinstall.yaml
  3 | echo 'storage:' >>/autoinstall.yaml
  4 | 
  5 | # 禁用 swap
  6 | cat <<EOF >>/autoinstall.yaml
  7 |   swap:
  8 |     size: 0
  9 | EOF
 10 | 
 11 | # 是用 size 寻找分区,number 没什么用
 12 | # https://curtin.readthedocs.io/en/latest/topics/storage.html
 13 | size_os=$(lsblk -bn -o SIZE /dev/disk/by-label/os)
 14 | 
 15 | # shellcheck disable=SC2154
 16 | if parted "/dev/$xda" print | grep '^Partition Table' | grep gpt; then
 17 |     # efi
 18 |     if [ -e /dev/disk/by-label/efi ]; then
 19 |         size_efi=$(lsblk -bn -o SIZE /dev/disk/by-label/efi)
 20 |         cat <<EOF >>/autoinstall.yaml
 21 |   config:
 22 |     # disk
 23 |     - ptable: gpt
 24 |       path: /dev/$xda
 25 |       preserve: true
 26 |       type: disk
 27 |       id: disk-xda
 28 |     # efi 分区
 29 |     - device: disk-xda
 30 |       size: $size_efi
 31 |       number: 1
 32 |       preserve: true
 33 |       grub_device: true
 34 |       type: partition
 35 |       id: partition-efi
 36 |     - fstype: fat32
 37 |       volume: partition-efi
 38 |       type: format
 39 |       id: format-efi
 40 |     # os 分区
 41 |     - device: disk-xda
 42 |       size: $size_os
 43 |       number: 2
 44 |       preserve: true
 45 |       type: partition
 46 |       id: partition-os
 47 |     - fstype: ext4
 48 |       volume: partition-os
 49 |       type: format
 50 |       id: format-os
 51 |     # mount
 52 |     - path: /
 53 |       device: format-os
 54 |       type: mount
 55 |       id: mount-os
 56 |     - path: /boot/efi
 57 |       device: format-efi
 58 |       type: mount
 59 |       id: mount-efi
 60 | EOF
 61 |     else
 62 |         # bios > 2t
 63 |         size_biosboot=$(parted "/dev/$xda" unit b print | grep bios_grub | awk '{print $4}' | sed 's/B$//')
 64 |         cat <<EOF >>/autoinstall.yaml
 65 |   config:
 66 |     # disk
 67 |     - ptable: gpt
 68 |       path: /dev/$xda
 69 |       preserve: true
 70 |       grub_device: true
 71 |       type: disk
 72 |       id: disk-xda
 73 |     # biosboot 分区
 74 |     - device: disk-xda
 75 |       size: $size_biosboot
 76 |       number: 1
 77 |       preserve: true
 78 |       type: partition
 79 |       id: partition-biosboot
 80 |     # os 分区
 81 |     - device: disk-xda
 82 |       size: $size_os
 83 |       number: 2
 84 |       preserve: true
 85 |       type: partition
 86 |       id: partition-os
 87 |     - fstype: ext4
 88 |       volume: partition-os
 89 |       type: format
 90 |       id: format-os
 91 |     # mount
 92 |     - path: /
 93 |       device: format-os
 94 |       type: mount
 95 |       id: mount-os
 96 | EOF
 97 |     fi
 98 | else
 99 |     # bios
100 |     cat <<EOF >>/autoinstall.yaml
101 |   config:
102 |     # disk
103 |     - ptable: msdos
104 |       path: /dev/$xda
105 |       preserve: true
106 |       grub_device: true
107 |       type: disk
108 |       id: disk-xda
109 |     # os 分区
110 |     - device: disk-xda
111 |       size: $size_os
112 |       number: 1
113 |       preserve: true
114 |       type: partition
115 |       id: partition-os
116 |     - fstype: ext4
117 |       volume: partition-os
118 |       type: format
119 |       id: format-os
120 |     # mount
121 |     - path: /
122 |       device: format-os
123 |       type: mount
124 |       id: mount-os
125 | EOF
126 | fi
127 | echo ... >>/autoinstall.yaml
128 | 


--------------------------------------------------------------------------------
/ubuntu.yaml:
--------------------------------------------------------------------------------
 1 | #cloud-config
 2 | # 顺序 early-commands > 安装系统 > late-commands > 重启进入系统 > cloud-init: runcmd > cloud-init: 其他
 3 | autoinstall:
 4 |   version: 1
 5 |   apt:
 6 |     fallback: offline-install
 7 |   source:
 8 |     id: "@SOURCE_ID@"
 9 |   kernel:
10 |     package: linux-generic
11 |   timezone: Asia/Shanghai
12 |   ssh:
13 |     allow-pw: true
14 |     authorized-keys: []
15 |     install-server: true
16 |   early-commands:
17 |     - |
18 |       # 解决 20.04 不能识别硬盘
19 |       # https://askubuntu.com/questions/1302392/ubuntu-server-20-04-setup-stuck-at-block-probing-did-not-discover-any-disks
20 |       mount | grep /isodevice && { losetup -d /dev/loop0; umount -l /isodevice; } || true
21 | 
22 |       # 提取 extra_confhome extra_kernel
23 |       prefix=extra
24 |       for var in $(grep -o "\b${prefix}_[^ ]*" /proc/cmdline | xargs); do
25 |           eval "$(echo $var | sed -E "s/${prefix}_([^=]*)=(.*)/\1='\2'/")"
26 |       done
27 | 
28 |       # 生成分区信息
29 |       xda=$(curl -L "$confhome/get-xda.sh" | sh -s)
30 |       export xda
31 |       curl -L "$confhome/ubuntu-storage-early.sh" | sh -s
32 | 
33 |       # 要安装的版本
34 |       # 有的镜像只有一个版本,没有 install-sources.yaml
35 |       # 因此提取不到 $source_id,此时 $source_id 参数为空
36 |       if [ -n "$source_id" ]; then
37 |           sed -i "s/@SOURCE_ID@/$source_id/" /autoinstall.yaml
38 |       else
39 |           sed -i "/@SOURCE_ID@/d" /autoinstall.yaml
40 |       fi
41 | 
42 |       # 内核风味
43 |       # https://bugs.launchpad.net/subiquity/+bug/1989353
44 |       sed -i "s/generic/$kernel/" /run/kernel-meta-package
45 |       sed -i "/package:/s/generic/$kernel/" /autoinstall.yaml
46 | 
47 |       # 跳过最后的更新
48 |       cp /usr/sbin/chroot /usr/sbin/chroot.bin
49 |       cat >/usr/sbin/chroot <<EOF
50 |       #!/bin/sh
51 |       [ "\$2" = "unattended-upgrades" ] || /usr/sbin/chroot.bin "\$@"
52 |       EOF
53 | 
54 |       # 禁用 DNS  强制离线安装内核和跳过最后的更新
55 |       # 但安装器会配置时区和写入最近的mirror到/etc/apt/sources.list 所以要提前解析
56 |       # dig会显示cname结果,cname会以.结尾,grep -v '\.
#39; 表示去除 cname 结果
57 |       # echo $(dig +short geoip.ubuntu.com | grep -v '\.
#39; | head -1) geoip.ubuntu.com >>/etc/hosts
58 |       # sed -i -E 's/(^nameserver )/#\1/' /etc/resolv.conf
59 |   late-commands:
60 |     - |
61 |       # root ssh 登录
62 |       echo "PermitRootLogin yes" >/target/etc/ssh/sshd_config.d/01-permitrootlogin.conf
63 | 
64 |       # 还原 DNS
65 |       # sed -i -E 's/^#(nameserver )/\1/' /etc/resolv.conf
66 | 
67 |       # 提取 extra_confhome
68 |       prefix=extra
69 |       for var in $(grep -o "\b${prefix}_[^ ]*" /proc/cmdline | xargs); do
70 |           eval "$(echo $var | sed -E "s/${prefix}_([^=]*)=(.*)/\1='\2'/")"
71 |       done
72 | 
73 |       # 下载合并分区脚本
74 |       cd /target
75 |       curl -LO $confhome/resize.sh
76 | 
77 |       # 升级 cloud-init
78 |       # curtin in-target --target=/target -- apt update
79 |       # curtin in-target --target=/target -- apt install --only-upgrade cloud-init
80 |   user-data:
81 |     runcmd:
82 |       - |
83 |         # 合并分区
84 |         bash /resize.sh
85 |     disable_root: false
86 |     users:
87 |       - name: root
88 |         lock_passwd: false
89 |     chpasswd:
90 |       expire: false
91 |       # 20.04 arm 需要
92 |       list: |
93 |         root:123@@@
94 |       users:
95 |         - name: root
96 |           password: 123@@@
97 |           type: text
98 | 


--------------------------------------------------------------------------------
/windows-allow-ping.bat:
--------------------------------------------------------------------------------
 1 | @echo off
 2 | mode con cp select=437 >nul
 3 | setlocal EnableDelayedExpansion
 4 | 
 5 | rem https://learn.microsoft.com/troubleshoot/windows-server/networking/netsh-advfirewall-firewall-control-firewall-behavior#command-example-4-configure-icmp-settings
 6 | rem 旧版命令 netsh firewall set icmpsetting 8 对应的配置是:文件和打印机共享(回显请求 - ICMPv4-In)
 7 | 
 8 | set ICMPv4EchoTypeNum=8
 9 | set ICMPv6EchoTypeNum=128
10 | 
11 | for %%i in (4, 6) do (
12 |     netsh advfirewall firewall add rule ^
13 |         name="ICMP Echo Request (ICMPv%%i-In)" ^
14 |         dir=in ^
15 |         action=allow ^
16 |         program=System ^
17 |         protocol=ICMPv%%i:!ICMPv%%iEchoTypeNum!,any
18 | )
19 | 
20 | rem 删除此脚本
21 | del "%~f0"
22 | 


--------------------------------------------------------------------------------
/windows-change-rdp-port.bat:
--------------------------------------------------------------------------------
 1 | @echo off
 2 | mode con cp select=437 >nul
 3 | 
 4 | rem set RdpPort=3333
 5 | 
 6 | rem https://learn.microsoft.com/windows-server/remote/remote-desktop-services/clients/change-listening-port
 7 | rem HKLM\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\FirewallRules
 8 | 
 9 | rem RemoteDesktop-Shadow-In-TCP
10 | rem v2.33|Action=Allow|Active=TRUE|Dir=In|Protocol=6|App=%SystemRoot%\system32\RdpSa.exe|Name=@FirewallAPI.dll,-28778|Desc=@FirewallAPI.dll,-28779|EmbedCtxt=@FirewallAPI.dll,-28752|Edge=TRUE|Defer=App|
11 | 
12 | rem RemoteDesktop-UserMode-In-TCP
13 | rem v2.33|Action=Allow|Active=TRUE|Dir=In|Protocol=6|LPort=3389|App=%SystemRoot%\system32\svchost.exe|Svc=termservice|Name=@FirewallAPI.dll,-28775|Desc=@FirewallAPI.dll,-28756|EmbedCtxt=@FirewallAPI.dll,-28752|
14 | 
15 | rem RemoteDesktop-UserMode-In-UDP
16 | rem v2.33|Action=Allow|Active=TRUE|Dir=In|Protocol=17|LPort=3389|App=%SystemRoot%\system32\svchost.exe|Svc=termservice|Name=@FirewallAPI.dll,-28776|Desc=@FirewallAPI.dll,-28777|EmbedCtxt=@FirewallAPI.dll,-28752|
17 | 
18 | rem 设置端口
19 | reg add "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" /v PortNumber /t REG_DWORD /d %RdpPort% /f
20 | 
21 | rem 设置防火墙
22 | rem 各个版本的防火墙自带的 rdp 规则略有不同
23 | rem 全部版本都有: program=%SystemRoot%\system32\svchost.exe service=TermService
24 | rem win7 还有:    program=System                            service=
25 | rem 以下为并集
26 | for %%a in (TCP, UDP) do (
27 |     netsh advfirewall firewall add rule ^
28 |         name="Remote Desktop - Custom Port (%%a-In)" ^
29 |         dir=in ^
30 |         action=allow ^
31 |         service=any ^
32 |         protocol=%%a ^
33 |         localport=%RdpPort%
34 | )
35 | 
36 | rem 家庭版没有 rdp 服务
37 | sc query TermService
38 | if %errorlevel% == 1060 goto :del
39 | 
40 | rem 重启服务 可以用 sc 或者 net
41 | rem UmRdpService 依赖 TermService
42 | rem sc stop 不能处理依赖关系,因此 sc stop TermService 前需要 sc stop UmRdpService
43 | rem net stop 可以处理依赖关系
44 | rem sc stop 是异步的,net stop 不是异步,但有 timeout 时间
45 | rem TermService 运行后,UmRdpService 会自动运行
46 | 
47 | rem 如果刚好系统在启动 rdp 服务,则会失败,因此要用 goto 循环
48 | rem The Remote Desktop Services service could not be stopped.
49 | 
50 | rem 有的机器会死循环,开机 logo 不断转圈
51 | rem 通过 netstat netstat -ano 可以看到端口已修改成功,但rdp服务不断重启 (pid一直改变)
52 | rem 因此限定重试次数避免死循环
53 | 
54 | set retryCount=5
55 | 
56 | :restartRDP
57 | if %retryCount% LEQ 0 goto :del
58 | net stop TermService /y && net start TermService || (
59 |     set /a retryCount-=1
60 |     timeout 10
61 |     goto :restartRDP
62 | )
63 | 
64 | :del
65 | del "%~f0"
66 | 


--------------------------------------------------------------------------------
/windows-del-gpo.bat:
--------------------------------------------------------------------------------
 1 | @echo off
 2 | mode con cp select=437 >nul
 3 | setlocal enabledelayedexpansion
 4 | 
 5 | set "files[1]=%windir%\System32\GroupPolicy\gpt.ini"
 6 | set "files[2]=%windir%\System32\GroupPolicy\Machine\Scripts\scripts.ini"
 7 | 
 8 | for %%i in (1 2) do (
 9 |     set "ini=!files[%%i]!"
10 |     if exist "!ini!.orig" (
11 |         move /y "!ini!.orig" "!ini!"
12 |     ) else (
13 |         del "!ini!"
14 |     )
15 | )
16 | 
17 | del "%~f0"
18 | 


--------------------------------------------------------------------------------
/windows-driver-utils.sh:
--------------------------------------------------------------------------------
  1 | #!/bin/ash
  2 | # shellcheck shell=dash
  3 | # shellcheck disable=SC3001,SC3003,SC3010
  4 | # reinstall.sh / trans.sh 共用此文件
  5 | 
  6 | # grep 无法处理 UTF-16LE 编码的 inf,有以下几种解决方法
  7 | # 1. 使用 ripgrep (rg) 或者 ugrep,但 cygwin 没有
  8 | # 2. grep -a a.b.c.d
  9 | # 3. iconv -f UTF-16 -t UTF-8
 10 | 
 11 | del_inf_comment() {
 12 |     sed 's/;.*//'
 13 | }
 14 | 
 15 | simply_inf() {
 16 |     convert_file_to_utf8 "$1" | del_cr | del_inf_comment | trim | del_empty_lines
 17 | }
 18 | 
 19 | convert_file_to_utf8() {
 20 |     # ash 用 * 比较字符串有问题
 21 |     # [[ 
#39;\xEF\xBB' = 
#39;\xEF\xBB*' ]] && echo 1
 22 | 
 23 |     # UTF-16LE without BOM 要处理吗? windows 支持这种编码的 inf?
 24 | 
 25 |     # UTF-16LE with BOM
 26 |     if [ "$(head -c2 "$1")" = 
#39;\xFF\xFE' ]; then
 27 |         # -f UTF-16LE -t UTF-8 会添加 UTF-8 BOM
 28 |         iconv -f UTF-16 -t UTF-8 "$1"
 29 | 
 30 |     # UTF-8 with BOM
 31 |     elif [ "$(head -c3 "$1")" = 
#39;\xEF\xBB\xBF' ]; then
 32 |         # busybox sed 不支持
 33 |         # sed '1s/^\xEF\xBB\xBF//' "$1"
 34 |         tail -c +4 "$1"
 35 | 
 36 |     # 其它
 37 |     else
 38 |         cat "$1"
 39 |     fi
 40 | }
 41 | 
 42 | simply_inf_word() {
 43 |     # 1 删除引号 "
 44 |     # 2 删除两边空格
 45 |     # 3 \ 和 .\ 换成 /
 46 |     # 4 连续的 / 替换成单个 /
 47 |     # 5 删除最前面的 /
 48 |     sed -E \
 49 |         -e 's,",,g' \
 50 |         -e 's/^[[:space:]]+//' -e 's/[[:space:]]+$//' \
 51 |         -e 's,\.?\\,/,g' \
 52 |         -e 's,/+,/,g' \
 53 |         -e 's,^/,,'
 54 | }
 55 | 
 56 | # reinstall.sh 下无法判断 iso 是 32 位还是 64 位,此时 mix_x86_x86_64 为 true
 57 | # trans.sh 下可以判断 iso 是 32 位还是 64 位,此时 mix_x86_x86_64 为 false
 58 | list_files_from_inf() {
 59 |     local inf=$1
 60 |     local arch=$2 # x86 amd64 arm64
 61 |     local mix_x86_x86_64=$3
 62 | 
 63 |     # 所有字段不区分大小写
 64 |     inf_txts=$(simply_inf "$inf" | to_lower)
 65 | 
 66 |     is_match_section() {
 67 |         local section=$1
 68 | 
 69 |         [ "$line" = "[$section]" ] || [ "$line" = "[$section.$arch]" ] ||
 70 |             { $mix_x86_x86_64 && [ "$arch" = x86 ] && [ "$line" = "[$section.amd64]" ]; } ||
 71 |             { $mix_x86_x86_64 && [ "$arch" = amd64 ] && [ "$line" = "[$section.x86]" ]; }
 72 |     }
 73 | 
 74 |     is_match_catalogfile() {
 75 |         local left
 76 |         left=$(echo "$line" | awk -F= '{print $1}' | simply_inf_word)
 77 | 
 78 |         # catalogfile.nt 是指所有 nt ?
 79 |         [ "$left" = "catalogfile" ] ||
 80 |             [ "$left" = "catalogfile.nt" ] ||
 81 |             [ "$left" = "catalogfile.nt$arch" ] ||
 82 |             { $mix_x86_x86_64 && [ "$arch" = x86 ] && [ "$left" = "catalogfile.ntamd64" ]; } ||
 83 |             { $mix_x86_x86_64 && [ "$arch" = amd64 ] && [ "$left" = "catalogfile.ntx86" ]; }
 84 |     }
 85 | 
 86 |     is_match_manufacturer_arch() {
 87 |         # x86 可写 NT / NTx86, 其它必须明确架构
 88 |         # https://learn.microsoft.com/en-us/windows-hardware/drivers/install/inf-manufacturer-section
 89 |         case "$arch" in
 90 |         x86) $mix_x86_x86_64 && regex='NT|NTx86|NTamd64' || regex='NT|NTx86' ;;
 91 |         amd64) $mix_x86_x86_64 && regex='NT|NTx86|NTamd64' || regex='NTamd64' ;;
 92 |         arm64) regex='NTarm64' ;;
 93 |         esac
 94 | 
 95 |         # 注意 cut awk 结果不同
 96 |         # 虽然在这里不会造成影响
 97 |         # echo 1 | cut -d, -f2-
 98 |         # 1
 99 |         # echo 1 | awk -F, '{print $2}'
100 |         # 空白
101 | 
102 |         echo "$line" | awk -F, '{for(i=2;i<=NF;i++) print $i}' | grep -Eiwq "$regex"
103 |     }
104 | 
105 |     # 还需要从 [Strings] 读取字符串?
106 | 
107 |     # 0. 检测 inf 是否适合当前架构
108 |     # 目前没有对比版本号
109 | 
110 |     ##############################################
111 |     # 注意这种情况, NTamd64.6.0 为空,表示不支持 6.0
112 | 
113 |     # [Manufacturer]
114 |     # %V_INTEL%   = Intel, NTamd64.6.0, NTamd64.6.1.1
115 | 
116 |     # [Intel.NTamd64.6.0]
117 |     # ; Empty section.
118 | 
119 |     # 如果后期改成不从 Manufacturer 获取支持的架构,而是从[]获取支持的架构,注意这种情况
120 |     # [Intel.NTamd64.10.0.1..22000]
121 |     ##############################################
122 | 
123 |     # 例子1
124 |     # [Manufacturer]
125 |     # %Amazon% = AWSNVME, NTamd64, NTARM64
126 | 
127 |     # 例子2
128 |     # [Manufacturer]
129 |     # %MyName% = MyName,NTx86.6.0,NTx86.5.1,
130 |     # .
131 |     # [MyName.NTx86.6.0] ; Empty section, so this INF does not support
132 |     # .                  ; NT 6.0 and later.
133 |     # .
134 |     # [MyName.NTx86.5.1] ; Used for NT 5.1 and later
135 |     # .                  ; (but not NT 6.0 and later due to the NTx86.6.0 entry)
136 |     # %MyDev% = InstallB,hwid
137 |     # .
138 |     # [MyName]           ; Empty section, so this INF does not support
139 |     # .                  ; Win2000
140 |     # .
141 | 
142 |     # 例子3
143 |     # 系统自带的驱动,没有 [Manufacturer]
144 | 
145 |     # 例子4
146 |     # C:\Windows\INF\wfcvsc.inf
147 |     # %StdMfg%=Standard,NTamd64...0x0000001,NTamd64...0x0000002,NTamd64...0x0000003
148 | 
149 |     in_section=false
150 |     arch_matched=false
151 |     has_manufacturer=false
152 |     # 未添加 IFS= 时,read 会删除行首行尾的空白字符
153 |     while read -r line; do
154 |         if [[ "$line" = "["* ]]; then
155 |             is_match_section manufacturer && has_manufacturer=true && in_section=true || in_section=false
156 |             continue
157 |         fi
158 | 
159 |         if $in_section; then
160 |             if is_match_manufacturer_arch; then
161 |                 arch_matched=true
162 |                 break
163 |             fi
164 |         fi
165 |     done < <(echo "$inf_txts")
166 | 
167 |     if $has_manufacturer && ! $arch_matched; then
168 |         return 10
169 |     fi
170 | 
171 |     # 1. 输出 .inf 文件名
172 |     basename "$inf"
173 | 
174 |     # 2. 输出 .cat 相对路径
175 |     # 例子
176 |     # [version]
177 |     # CatalogFile = "xxxxx.cat"
178 |     # CatalogFile.NTAMD64=Balloon.cat
179 |     in_section=false
180 |     # 未添加 IFS= 时,read 会删除行首行尾的空白字符
181 |     while read -r line; do
182 |         if [[ "$line" = "["* ]]; then
183 |             is_match_section version && in_section=true || in_section=false
184 |             continue
185 |         fi
186 | 
187 |         if $in_section && is_match_catalogfile; then
188 |             echo "$line" | awk -F= '{print $2}' | simply_inf_word
189 |         fi
190 |     done < <(echo "$inf_txts")
191 | 
192 |     # 3. 获取 SourceDisksNames
193 |     # 例子
194 |     # [SourceDisksNames]
195 |     # 1 = "Windows NT CD-ROM",file.tag,, "\common"
196 |     SourceDisksNames=
197 |     in_section=false
198 |     # 未添加 IFS= 时,read 会删除行首行尾的空白字符
199 |     while read -r line; do
200 |         if [[ "$line" = "["* ]]; then
201 |             is_match_section sourcedisksnames && in_section=true || in_section=false
202 |             continue
203 |         fi
204 |         # 注意可能有空格和引号
205 | 
206 |         if $in_section; then
207 |             local num dir
208 |             num=$(echo "$line" | awk -F= '{print $1}' | simply_inf_word)
209 |             dir=$(echo "$line" | awk -F, '{print $4}' | simply_inf_word)
210 |             # 每行一条记录
211 |             if [ -n "$SourceDisksNames" ]; then
212 |                 SourceDisksNames=$SourceDisksNames
#39;\n'
213 |             fi
214 |             SourceDisksNames="$SourceDisksNames$num:$dir"
215 |         fi
216 |     done < <(echo "$inf_txts")
217 | 
218 |     # 4. 打印 SourceDisksFiles 的绝对路径
219 |     # 例子
220 |     # [SourceDisksFiles]
221 |     # aha154x.sys = 1 , "\x86" ,,
222 |     in_section=false
223 |     # 未添加 IFS= 时,read 会删除行首行尾的空白字符
224 |     while read -r line; do
225 |         if [[ "$line" = "["* ]]; then
226 |             is_match_section sourcedisksfiles && in_section=true || in_section=false
227 |             continue
228 |         fi
229 | 
230 |         if $in_section; then
231 |             file=$(echo "$line" | awk -F= '{print $1}' | simply_inf_word)
232 |             num=$(echo "$line" | awk -F'=|,' '{print $2}' | simply_inf_word)
233 |             sub_dir=$(echo "$line" | awk -F, '{print $2}' | simply_inf_word)
234 |             # 可能有多个
235 |             while IFS= read -r parent_dir; do
236 |                 echo "$parent_dir/$sub_dir/$file" | simply_inf_word
237 |             done < <(echo "$SourceDisksNames" | awk -F: "\$1==\"$num\" {print \$2}")
238 |         fi
239 |     done < <(echo "$inf_txts")
240 | }
241 | 
242 | # windows 安装驱动时,只会安装相同架构的驱动文件到系统,即使 inf 里有列出其它架构的驱动
243 | # 因此 DISM 导出驱动时,也就没有包含其它架构的驱动文件
244 | 
245 | # 用于尽可能匹配路径大小写
246 | get_path_in_correct_case() {
247 |     # 同时支持参数和管道
248 |     local path
249 |     path=$({ if [ -n "$1" ]; then echo "$1"; else cat; fi; })
250 | 
251 |     # 用 / 分割路径,提取成列表
252 |     # 例如: ///a///b/c.inf -> a b c.inf
253 |     # shellcheck disable=SC2046
254 |     set -- $(echo "$path" | grep -o '[^/]*')
255 |     (
256 |         local output=
257 |         if is_absolute_path "$path"; then
258 |             cd /
259 |             output=/
260 |         fi
261 | 
262 |         stop_find=false
263 | 
264 |         while [ $# -gt 0 ]; do
265 |             local part=$1
266 |             local tmp
267 |             # shellcheck disable=SC2010
268 |             if ! $stop_find; then
269 |                 if tmp=$(ls -1 | grep -Fix "$part"); then
270 |                     part=$tmp
271 |                     # 大于 1 表示当前 part 是目录
272 |                     if [ $# -gt 1 ]; then
273 |                         if ! cd "$part" 2>/dev/null; then
274 |                             warn "Can't cd $path"
275 |                             stop_find=true
276 |                         fi
277 |                     fi
278 |                 else
279 |                     stop_find=true
280 |                 fi
281 |             fi
282 | 
283 |             if [ $# -gt 1 ]; then
284 |                 output="$output$part/"
285 |             else
286 |                 # 最后 part
287 |                 output="$output$part"
288 |             fi
289 |             shift
290 |         done
291 | 
292 |         echo "$output"
293 |     )
294 | }
295 | 
296 | is_file_or_link() {
297 |     # -e / -f 坏软连接,返回 false
298 |     # -L 坏软连接,返回 true
299 |     [ -f "$1" ] || [ -L "$1" ]
300 | }
301 | 
302 | find_file_ignore_case() {
303 |     # 同时支持参数和管道
304 |     local path
305 |     path=$({ if [ -n "$1" ]; then echo "$1"; else cat; fi; })
306 | 
307 |     path=$(get_path_in_correct_case "$path")
308 |     if is_file_or_link "$path"; then
309 |         echo "$path"
310 |     else
311 |         warn "Can't find $path" >&2
312 |         return 1
313 |     fi
314 | }
315 | 
316 | parse_inf_and_cp_driever() {
317 |     local inf=$1
318 |     local dst=$2
319 |     local arch=$3
320 |     local mix_x86_x86_64=$4
321 | 
322 |     info false "Add driver: $inf"
323 | 
324 |     # 首先创建目录,否则无法通过 ls 文件数得到编号
325 |     mkdir -p "$dst"
326 |     # shellcheck disable=SC2012
327 |     inf_index=$(($(ls -1 "$dst" | wc -l) + 1))
328 |     inf_old_dir=$(dirname "$inf")
329 |     inf_new_dir=$dst/$inf_index
330 |     if driver_files=$(list_files_from_inf "$inf" "$arch" "$mix_x86_x86_64"); then
331 |         mkdir -p "$inf_new_dir"
332 |         (
333 |             cd "$inf_old_dir" || error_and_exit "Can't cd $inf_old_dir"
334 |             while read -r file; do
335 |                 if file=$(find_file_ignore_case "$file"); then
336 |                     cp -v --parents "$file" "$inf_new_dir"
337 |                 fi
338 |             done < <(echo "$driver_files")
339 |         )
340 |     else
341 |         if [ $? -eq 10 ]; then
342 |             warn "$inf arch not match."
343 |         else
344 |             error_and_exit "Unknown error while parse $inf."
345 |         fi
346 |     fi
347 | }
348 | 
349 | get_sys_dir_for_eth() {
350 |     (
351 |         cd "$(readlink -f "/sys/class/net/$1")" || error_and_exit "Can't cd to $1"
352 |         while ! [ "$(pwd)" = / ]; do
353 |             # DRIVER=virtio-pci
354 |             # PCI_CLASS=20000            # 2 开头表示网络设备
355 |             # PCI_ID=1AF4:1041
356 |             # PCI_SUBSYS_ID=1AF4:1100
357 |             # PCI_SLOT_NAME=0000:03:00.0
358 |             if [ -f uevent ] && grep -q 'PCI_CLASS=2' uevent && grep -q 'PCI_ID' uevent; then
359 |                 pwd
360 |                 return
361 |             fi
362 |             cd ..
363 |         done
364 |         return 1
365 |     )
366 | }
367 | 


--------------------------------------------------------------------------------
/windows-frpc.bat:
--------------------------------------------------------------------------------
 1 | @echo off
 2 | mode con cp select=437 >nul
 3 | 
 4 | rem Windows Deferder 会误报,因此要添加白名单
 5 | powershell -ExecutionPolicy Bypass -Command "Add-MpPreference -ExclusionPath '%SystemDrive%\frpc\frpc.exe'"
 6 | 
 7 | rem 启用日志
 8 | rem wevtutil set-log Microsoft-Windows-TaskScheduler/Operational /enabled:true
 9 | 
10 | rem 创建计划任务并立即运行
11 | schtasks /Create /TN "frpc" /XML "%SystemDrive%\frpc\frpc.xml"
12 | schtasks /Run /TN "frpc"
13 | del "%SystemDrive%\frpc\frpc.xml"
14 | 
15 | rem win10+ 在首次登录后计划任务才生效
16 | rem 即使手动重启,计划任务也没有运行
17 | 
18 | rem 如果 10 秒内有 frpc 进程,则代表计划任务已经生效,不需要首次登录
19 | rem 如果 10 秒后也没有 frpc 进程,则需要临时改用 SYSTEM 用户运行计划任务
20 | for /L %%i in (1,1,10) do (
21 |     timeout 1
22 |     tasklist /FI "IMAGENAME eq frpc.exe" | find /I "frpc.exe" && (
23 |         goto :end
24 |     )
25 | )
26 | 
27 | rem 临时改用 SYSTEM 用户运行计划任务,运行后再改回 Local Service 用户
28 | schtasks /Change /TN "frpc" /RU "S-1-5-18"
29 | schtasks /Run /TN "frpc"
30 | schtasks /Change /TN "frpc" /RU "S-1-5-19"
31 | 
32 | :end
33 | rem 删除此脚本
34 | del "%~f0"
35 | 


--------------------------------------------------------------------------------
/windows-frpc.xml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bin456789/reinstall/02ae82128f96702a4c0caade2414e8457434fe1d/windows-frpc.xml


--------------------------------------------------------------------------------
/windows-resize.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | mode con cp select=437 >nul
3 | 
4 | set C=%SystemDrive:~0,1%
5 | for /f "tokens=2" %%a in ('echo list vol ^| diskpart ^| findstr "\<installer\>"') do (echo select vol %%a & echo delete partition) | diskpart
6 | for /f "tokens=2" %%a in ('echo list vol ^| diskpart ^| findstr "\<%C%\>"') do (echo select vol %%a & echo extend) | diskpart
7 | del "%~f0"
8 | 


--------------------------------------------------------------------------------
/windows-set-netconf.bat:
--------------------------------------------------------------------------------
 1 | rem set mac_addr=11:22:33:aa:bb:cc
 2 | 
 3 | rem set ipv4_addr=192.168.1.2/24
 4 | rem set ipv4_gateway=192.168.1.1
 5 | rem set ipv4_dns1=192.168.1.1
 6 | rem set ipv4_dns2=192.168.1.2
 7 | 
 8 | rem set ipv6_addr=2222::2/64
 9 | rem set ipv6_gateway=2222::1
10 | rem set ipv6_dns1=::1
11 | rem set ipv6_dns2=::2
12 | 
13 | @echo off
14 | mode con cp select=437 >nul
15 | setlocal EnableDelayedExpansion
16 | 
17 | rem 禁用 IPv6 地址标识符的随机化,防止 IPv6 和后台面板不一致
18 | netsh interface ipv6 set global randomizeidentifiers=disabled
19 | 
20 | rem 检查是否定义了 MAC 地址
21 | if defined mac_addr (
22 |     for /f %%a in ('wmic nic where "MACAddress='%mac_addr%'" get InterfaceIndex ^| findstr [0-9]') do set id=%%a
23 |     if defined id (
24 |         rem 配置静态 IPv4 地址和网关
25 |         if defined ipv4_addr if defined ipv4_gateway (
26 |         rem gwmetric 默认值为 1,自动跃点需设为 0
27 |             netsh interface ipv4 set address !id! static !ipv4_addr! gateway=!ipv4_gateway! gwmetric=0
28 |         )
29 | 
30 |         rem 配置静态 IPv4 DNS 服务器
31 |         for %%i in (1, 2) do (
32 |             if defined ipv4_dns%%i (
33 |                 netsh interface ipv4 add | findstr "dnsservers"
34 |                 if ErrorLevel 1 (
35 |                     rem vista
36 |                     netsh interface ipv4 add dnsserver !id! !ipv4_dns%%i! %%i
37 |                 ) else (
38 |                     rem win7
39 |                     netsh interface ipv4 add dnsservers !id! !ipv4_dns%%i! %%i no
40 |                 )
41 |             )
42 |         )
43 | 
44 |         rem 配置 IPv6 地址和网关
45 |         if defined ipv6_addr if defined ipv6_gateway (
46 |             netsh interface ipv6 set address !id! !ipv6_addr!
47 |             netsh interface ipv6 add route prefix=::/0 !id! !ipv6_gateway!
48 |         )
49 | 
50 |         rem 配置 IPv6 DNS 服务器
51 |         for %%i in (1, 2) do (
52 |             if defined ipv6_dns%%i (
53 |                 netsh interface ipv6 add | findstr "dnsservers"
54 |                 if ErrorLevel 1 (
55 |                     rem vista
56 |                     netsh interface ipv6 add dnsserver !id! !ipv6_dns%%i! %%i
57 |                 ) else (
58 |                     rem win7
59 |                     netsh interface ipv6 add dnsservers !id! !ipv6_dns%%i! %%i no
60 |                 )
61 |             )
62 |         )
63 |     )
64 | )
65 | 
66 | rem 删除此脚本
67 | del "%~f0"
68 | 


--------------------------------------------------------------------------------
/windows-setup.bat:
--------------------------------------------------------------------------------
  1 | @echo off
  2 | mode con cp select=437 >nul
  3 | 
  4 | rem 还原 setup.exe
  5 | rename X:\setup.exe.disabled setup.exe
  6 | 
  7 | rem 等待 10 秒才自动安装
  8 | cls
  9 | for /l %%i in (10,-1,1) do (
 10 |     echo Press Ctrl+C within %%i seconds to cancel the automatic installation.
 11 |     call :sleep 1000
 12 |     cls
 13 | )
 14 | 
 15 | rem win7 find 命令在 65001 代码页下有问题,仅限 win 7
 16 | rem findstr 就正常,但安装程序又没有 findstr
 17 | rem echo a | find "a"
 18 | 
 19 | rem 使用高性能模式
 20 | rem https://learn.microsoft.com/windows-hardware/manufacture/desktop/capture-and-apply-windows-using-a-single-wim
 21 | rem win8 pe 没有 powercfg
 22 | powercfg /s SCHEME_MIN 2>nul
 23 | 
 24 | rem 安装 SCSI 驱动
 25 | if exist X:\drivers\ (
 26 |     for /f "delims=" %%F in ('dir /s /b "X:\drivers\*.inf" 2^>nul') do (
 27 |         call :drvload_if_scsi "%%~F"
 28 |     )
 29 | 
 30 |     rem 官网写了可以安装但仅会加载关键驱动
 31 |     rem Gcore 的 virtio-gpu 在安装时没有显示
 32 |     rem 即使安装时加载了显卡驱动
 33 |     rem 进入系统后才有显示
 34 |     rem find /i "viogpudo" "%%~F" >nul
 35 |     rem if not errorlevel 1 (
 36 |     rem     drvload "%%~F"
 37 |     rem )
 38 | )
 39 | 
 40 | rem 安装自定义 SCSI 驱动
 41 | rem 可以用 forfiles /p X:\custom_drivers /m *.inf /c "cmd /c echo @path"
 42 | rem 不可以用 for %%F in ("X:\custom_drivers\*\*.inf")
 43 | if exist X:\custom_drivers\ (
 44 |     for /f "delims=" %%F in ('dir /s /b "X:\custom_drivers\*.inf" 2^>nul') do (
 45 |         call :drvload_if_scsi "%%~F"
 46 |     )
 47 | )
 48 | 
 49 | rem 等待加载分区
 50 | call :sleep 5000
 51 | echo rescan | diskpart
 52 | 
 53 | rem 判断 efi 还是 bios
 54 | rem 或者用 https://learn.microsoft.com/windows-hardware/manufacture/desktop/boot-to-uefi-mode-or-legacy-bios-mode
 55 | rem pe 下没有 mountvol
 56 | echo list vol | diskpart | find "efi" && (
 57 |     set BootType=efi
 58 | ) || (
 59 |     set BootType=bios
 60 | )
 61 | 
 62 | rem 获取 ProductType
 63 | rem for /f "tokens=3" %%a in ('reg query "HKLM\SYSTEM\CurrentControlSet\Control\ProductOptions" /v ProductType') do (
 64 | rem     set "ProductType=%%a"
 65 | rem )
 66 | 
 67 | rem 获取 BuildNumber
 68 | for /f "tokens=3" %%a in ('reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /v CurrentBuildNumber') do (
 69 |     set "BuildNumber=%%a"
 70 | )
 71 | 
 72 | rem 获取 installer 卷 id
 73 | for /f "tokens=2" %%a in ('echo list vol ^| diskpart ^| find "installer"') do (
 74 |     set "VolIndex=%%a"
 75 | )
 76 | 
 77 | rem 将 installer 分区设为 Y 盘
 78 | (echo select vol %VolIndex% & echo assign letter=Y) | diskpart
 79 | 
 80 | rem 旧版安装程序会自动在 C 盘设置虚拟内存
 81 | rem 新版安装程序(24h2)不会自动设置虚拟内存
 82 | rem 在 installer 分区创建虚拟内存,不用白不用
 83 | call :createPageFile
 84 | 
 85 | rem 查看虚拟内存
 86 | rem wmic pagefile
 87 | 
 88 | rem 获取主硬盘 id
 89 | rem vista pe 没有 wmic,因此用 diskpart
 90 | (echo select vol %VolIndex% & echo list disk) | diskpart | find "* Disk " > X:\disk.txt
 91 | for /f "tokens=3" %%a in (X:\disk.txt) do (
 92 |     set "DiskIndex=%%a"
 93 | )
 94 | del X:\disk.txt
 95 | 
 96 | rem 这个变量会被 trans.sh 修改
 97 | set is4kn=0
 98 | if "%is4kn%"=="1" (
 99 |     set EFISize=260
100 | ) else (
101 |     set EFISize=100
102 | )
103 | 
104 | rem 重新分区/格式化
105 | (if "%BootType%"=="efi" (
106 |     echo select disk %DiskIndex%
107 | 
108 |     echo select part 1
109 |     echo delete part override
110 |     echo select part 2
111 |     echo delete part override
112 |     echo select part 3
113 |     echo delete part override
114 | 
115 |     echo create part efi size=%EFISize%
116 |     echo format fs=fat32 quick
117 | 
118 |     echo create part msr size=16
119 | 
120 |     echo create part primary
121 |     echo format fs=ntfs quick
122 |     rem echo assign letter=Z
123 | ) else (
124 |     echo select disk %DiskIndex%
125 | 
126 |     echo select part 1
127 |     rem echo delete part override
128 |     rem echo create part primary
129 |     echo format fs=ntfs quick
130 |     echo active
131 |     rem echo assign letter=Z
132 | )) > X:\diskpart.txt
133 | 
134 | rem 使用 diskpart /s ,出错不会执行剩下的 diskpart 命令
135 | diskpart /s X:\diskpart.txt
136 | del X:\diskpart.txt
137 | 
138 | rem 盘符
139 | rem X boot.wim (ram)
140 | rem Y installer
141 | rem Z os
142 | 
143 | rem 旧版安装程序会自动在C盘设置虚拟内存,新版安装程序(24h2)不会
144 | rem 如果不创建虚拟内存,1g 内存的机器安装时会报错/杀进程
145 | if %BuildNumber% GEQ 26040 (
146 |     rem 已经在 installer 分区创建了虚拟内存,约等于 boot.wim 的大小,因此这步不需要
147 |     rem vista/2008 没有删除 boot.wim,200M预留空间-(文件系统占用+驱动占用)后,实测能创建1个64M虚拟内存文件
148 |     rem call :createPageFileOnZ
149 | )
150 | 
151 | rem 设置应答文件的主硬盘 id
152 | set "file=X:\windows.xml"
153 | set "tempFile=X:\tmp.xml"
154 | 
155 | set "search=%%disk_id%%"
156 | set "replace=%DiskIndex%"
157 | 
158 | (for /f "delims=" %%i in (%file%) do (
159 |     set "line=%%i"
160 | 
161 |     setlocal EnableDelayedExpansion
162 |     echo !line:%search%=%replace%!
163 |     endlocal
164 | 
165 | )) > %tempFile%
166 | move /y %tempFile% %file%
167 | 
168 | 
169 | rem https://github.com/pbatard/rufus/issues/1990
170 | for %%a in (RAM TPM SecureBoot) do (
171 |     reg add HKLM\SYSTEM\Setup\LabConfig /t REG_DWORD /v Bypass%%aCheck /d 1 /f
172 | )
173 | 
174 | rem 设置
175 | set ForceOldSetup=0
176 | set EnableUnattended=1
177 | set EnableEMS=0
178 | 
179 | rem 运行 ramdisk X:\setup.exe 的话
180 | rem vista 会找不到安装源
181 | rem server 23h2 会无法运行
182 | rem 使用 /installfrom 可以解决?
183 | if "%ForceOldSetup%"=="1" (
184 |     set setup=Y:\sources\setup.exe
185 | ) else (
186 |     set setup=Y:\setup.exe
187 | )
188 | 
189 | if "%EnableUnattended%"=="1" (
190 |     set Unattended=/unattend:X:\windows.xml
191 | )
192 | 
193 | rem 新版安装程序默认开了 Compact OS
194 | 
195 | rem 新版安装程序不会创建 BIOS MBR 引导
196 | rem 因此要回退到旧版,或者手动修复 MBR
197 | rem server 2025 + bios 也是
198 | rem 但是 server 2025 官网写支持 bios
199 | rem TODO: 使用 ms-sys 可以不修复?
200 | if %BuildNumber% GEQ 26040 if "%BootType%"=="bios" (
201 |     rem set ForceOldSetup=1
202 |     bootrec /fixmbr
203 | )
204 | 
205 | rem 旧版安装程序不会创建 winre 分区
206 | rem 新版安装程序会创建 winre 分区
207 | rem winre 分区创建在 installer 分区前面
208 | rem 禁止 winre 分区后,winre 储存在 C 盘,依然有效
209 | if %BuildNumber% GEQ 26040 if "%ForceOldSetup%"=="0" (
210 |     set ResizeRecoveryPartition=/ResizeRecoveryPartition Disable
211 | )
212 | 
213 | rem 为 windows server 打开 EMS/SAC
214 | rem 普通 windows 没有自带 SAC 组件,暂不处理
215 | rem 现在通过 trans.sh 准确检测系统是否有 SAC 组件,有则修改 EnableEMS 变量打开 EMS
216 | if "%EnableEMS%"=="1" (
217 |     rem set EMS=/EMSPort:UseBIOSSettings /EMSBaudRate:115200
218 |     set EMS=/EMSPort:COM1 /EMSBaudRate:115200
219 | )
220 | 
221 | echo on
222 | %setup% %ResizeRecoveryPartition% %EMS% %Unattended%
223 | exit /b
224 | 
225 | :sleep
226 | rem 没有加载网卡驱动,无法用 ping 来等待
227 | rem 没有 timeout 命令
228 | rem timeout /t 10 /nobreak
229 | echo wscript.sleep(%~1) > X:\sleep.vbs
230 | cscript //nologo X:\sleep.vbs
231 | del X:\sleep.vbs
232 | exit /b
233 | 
234 | :createPageFile
235 | rem 尽量填满空间,pagefile 默认 64M
236 | for /l %%i in (1, 1, 100) do (
237 |     wpeutil CreatePageFile /path=Y:\pagefile%%i.sys >nul 2>nul && echo Created pagefile%%i.sys || exit /b
238 | )
239 | exit /b
240 | 
241 | :createPageFileOnZ
242 | wpeutil CreatePageFile /path=Z:\pagefile.sys /size=512
243 | exit /b
244 | 
245 | :drvload_if_scsi
246 | rem 不要查找 Class=SCSIAdapter 因为有些驱动等号两边有空格
247 | find /i "SCSIAdapter" "%~1" >nul
248 | if not errorlevel 1 (
249 |     drvload "%~1"
250 | )
251 | exit /b
252 | 


--------------------------------------------------------------------------------
/windows.xml:
--------------------------------------------------------------------------------
  1 | <?xml version="1.0" encoding="utf-8"?>
  2 | <unattend xmlns="urn:schemas-microsoft-com:unattend">
  3 | 
  4 |     <settings pass="windowsPE">
  5 |         <component name="Microsoft-Windows-Setup" processorArchitecture="%arch%" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  6 |             <!-- 安装过程可节省一点内存?vista 要删除不然报错 -->
  7 |             <EnableFirewall>false</EnableFirewall>
  8 |             <UserData>
  9 |                 <AcceptEula>true</AcceptEula>
 10 |                 <ProductKey>
 11 |                     <Key>%key%</Key>
 12 |                 </ProductKey>
 13 |             </UserData>
 14 |             <ImageInstall>
 15 |                 <OSImage>
 16 |                     <InstallFrom>
 17 |                         <MetaData wcm:action="add">
 18 |                             <Key>/IMAGE/NAME</Key>
 19 |                             <Value>%image_name%</Value>
 20 |                         </MetaData>
 21 |                     </InstallFrom>
 22 |                     <InstallTo>
 23 |                         <DiskID>%disk_id%</DiskID>
 24 |                         <PartitionID>%installto_partitionid%</PartitionID>
 25 |                     </InstallTo>
 26 |                 </OSImage>
 27 |             </ImageInstall>
 28 |             <!-- 用注册表无法绕过 cpu 核数限制 -->
 29 |             <!-- https://github.com/pbatard/rufus/issues/1990 -->
 30 |             <!-- https://learn.microsoft.com/windows/iot/iot-enterprise/Hardware/System_Requirements -->
 31 |             <!-- <RunSynchronous>
 32 |                 <RunSynchronousCommand wcm:action="add">
 33 |                     <Order>1</Order>
 34 |                     <Path>cmd /c for %a in (RAM TPM SecureBoot) do reg add HKLM\SYSTEM\Setup\LabConfig /t REG_DWORD /v Bypass%aCheck /d 1 /f</Path>
 35 |                 </RunSynchronousCommand>
 36 |             </RunSynchronous> -->
 37 |         </component>
 38 |         <component name="Microsoft-Windows-International-Core-WinPE" processorArchitecture="%arch%" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 39 |             <InputLocale>%locale%</InputLocale>
 40 |             <SystemLocale>%locale%</SystemLocale>
 41 |             <UILanguage>%locale%</UILanguage>
 42 |             <UserLocale>%locale%</UserLocale>
 43 |         </component>
 44 |     </settings>
 45 | 
 46 |     <!-- vultr win8/8.1/2012/2012r2 在 windowsPE/Microsoft-Windows-PnpCustomizationsWinPE 下载加载气球驱动
 47 |     会出现 Windows Cannot find Microsoft software license terms 错误 -->
 48 | 
 49 |     <settings pass="offlineServicing">
 50 |         <component name="Microsoft-Windows-PnpCustomizationsNonWinPE" processorArchitecture="%arch%" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 51 |             <DriverPaths>
 52 |                 <!-- 目录为空不会报错 -->
 53 |                 <!-- 驱动可以放在子目录 -->
 54 |                 <PathAndCredentials wcm:action="add" wcm:keyValue="1">
 55 |                     <Path>X:\drivers</Path>
 56 |                 </PathAndCredentials>
 57 |                 <PathAndCredentials wcm:action="add" wcm:keyValue="2">
 58 |                     <Path>X:\custom_drivers</Path>
 59 |                 </PathAndCredentials>
 60 |             </DriverPaths>
 61 |         </component>
 62 |     </settings>
 63 | 
 64 |     <settings pass="specialize">
 65 |         <component name="Microsoft-Windows-Deployment" processorArchitecture="%arch%" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 66 |             <RunSynchronous>
 67 |                 <!-- 大厂都要求设置高性能和从不关闭显示器
 68 |                 https://learn.microsoft.com/en-us/azure/virtual-machines/windows/prepare-for-upload-vhd-image#set-windows-configurations-for-azure
 69 |                 https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/migrating-latest-types.html
 70 |                 https://support.huaweicloud.com/usermanual-ims/zh-cn_topic_0047501112.html
 71 |                 powercfg /aliases 能显示 GUID/名称 的对应关系,vista 也能使用名称 -->
 72 |                 <RunSynchronousCommand wcm:action="add">
 73 |                     <Order>1</Order>
 74 |                     <Path>powercfg /setacvalueindex SCHEME_BALANCED SUB_VIDEO VIDEOIDLE 0</Path>
 75 |                 </RunSynchronousCommand>
 76 |                 <RunSynchronousCommand wcm:action="add">
 77 |                     <Order>2</Order>
 78 |                     <Path>powercfg /setacvalueindex SCHEME_MIN SUB_VIDEO VIDEOIDLE 0</Path>
 79 |                 </RunSynchronousCommand>
 80 |                 <RunSynchronousCommand wcm:action="add">
 81 |                     <Order>3</Order>
 82 |                     <Path>powercfg /setacvalueindex SCHEME_MAX SUB_VIDEO VIDEOIDLE 0</Path>
 83 |                 </RunSynchronousCommand>
 84 |                 <!-- 设为高性能 -->
 85 |                 <RunSynchronousCommand wcm:action="add">
 86 |                     <Order>4</Order>
 87 |                     <Path>powercfg /setactive SCHEME_MIN</Path>
 88 |                 </RunSynchronousCommand>
 89 |                 <!-- 启用 administrator 账户 -->
 90 |                 <RunSynchronousCommand wcm:action="add">
 91 |                     <Order>5</Order>
 92 |                     <!-- vista 没有自带 powershell -->
 93 |                     <!-- <Path>powershell "$User = Get-WmiObject Win32_UserAccount | where SID -like *-500; $User.Disabled = $False; $User.Put()"</Path> -->
 94 |                     <!-- win7 此时无法用 wmic useraccount -->
 95 |                     <!-- <Path>wmic useraccount where "sid like '%-500'" set Disabled=false</Path> -->
 96 |                     <!-- https://learn.microsoft.com/archive/technet-wiki/13813.localized-names-for-administrator-account-in-windows -->
 97 |                     <Path>cmd /c "for %a in (Administrator Administrador Administrateur Administratör Администратор Järjestelmänvalvoja Rendszergazda) do (net user %a /active:yes &amp;&amp; exit)"</Path>
 98 |                 </RunSynchronousCommand>
 99 |                 <!-- 禁用保留空间 -->
100 |                 <RunSynchronousCommand wcm:action="add">
101 |                     <Order>6</Order>
102 |                     <Path>reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\ReserveManager /v ShippedWithReserves /t REG_DWORD /d 0 /f</Path>
103 |                     <!-- 此时以下命令无效 -->
104 |                     <!-- <Path>DISM /Online /Set-ReservedStorageState /State:Disabled</Path> -->
105 |                     <!-- <Path>powershell "Set-WindowsReservedStorageState -State Disabled; exit"</Path> -->
106 |                 </RunSynchronousCommand>
107 |                 <!-- win7 在此阶段找不到网卡 -->
108 |                 <!-- <RunSynchronousCommand wcm:action="add">
109 |                     <Order>5</Order>
110 |                     <Path>cmd /c "if exist %SystemDrive%\windows-resize.bat (call %SystemDrive%\windows-resize.bat)"</Path>
111 |                 </RunSynchronousCommand>
112 |                 <RunSynchronousCommand wcm:action="add">
113 |                     <Order>6</Order>
114 |                     <Path>cmd /c "if exist %SystemDrive%\windows-set-netconf.bat (call %SystemDrive%\windows-set-netconf.bat)"</Path>
115 |                 </RunSynchronousCommand> -->
116 |             </RunSynchronous>
117 |         </component>
118 |         <component name="Microsoft-Windows-TerminalServices-LocalSessionManager" processorArchitecture="%arch%" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
119 |             <fDenyTSConnections>false</fDenyTSConnections>
120 |         </component>
121 |         <component name="Networking-MPSSVC-Svc" processorArchitecture="%arch%" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
122 |             <FirewallGroups>
123 |                 <FirewallGroup wcm:action="add" wcm:keyValue="RemoteDesktop">
124 |                     <Profile>all</Profile>
125 |                     <!-- HKLM\System\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\FirewallRules -->
126 |                     <!-- Get-NetFirewallRule | Where-Object Name -like 'RemoteDesktop*' | fl Name,DisplayName,Description,DisplayGroup,Group -->
127 |                     <!-- https://learn.microsoft.com/windows-hardware/customize/desktop/unattend/networking-mpssvc-svc-firewallgroups-firewallgroup-group -->
128 |                     <Group>@FirewallAPI.dll,-28752</Group>
129 |                     <Active>%use_default_rdp_port%</Active>
130 |                 </FirewallGroup>
131 |             </FirewallGroups>
132 |         </component>
133 |         <component name="Microsoft-Windows-powercpl" processorArchitecture="%arch%" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
134 |             <PreferredPlan>8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c</PreferredPlan>
135 |         </component>
136 |         <component name="Microsoft-Windows-ErrorReportingCore" processorArchitecture="%arch%" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
137 |             <DisableWER>1</DisableWER>
138 |         </component>
139 |         <component name="Microsoft-Windows-SQMApi" processorArchitecture="%arch%" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
140 |             <CEIPEnabled>0</CEIPEnabled>
141 |         </component>
142 |     </settings>
143 | 
144 |     <settings pass="oobeSystem">
145 |         <!-- 好像不起作用 -->
146 |         <!-- <component name="Microsoft-Windows-WinRE-RecoveryAgent" processorArchitecture="%arch%" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
147 |             <UninstallWindowsRE>true</UninstallWindowsRE>
148 |         </component> -->
149 |         <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="%arch%" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
150 |             <UserAccounts>
151 |                 <AdministratorPassword>
152 |                     <Value>%administrator_password%</Value>
153 |                     <PlainText>false</PlainText>
154 |                 </AdministratorPassword>
155 |             </UserAccounts>
156 |             <OOBE>
157 |                 <HideEULAPage>true</HideEULAPage>
158 |                 <ProtectYourPC>3</ProtectYourPC>
159 |                 <SkipMachineOOBE>true</SkipMachineOOBE>
160 |                 <SkipUserOOBE>true</SkipUserOOBE>
161 |             </OOBE>
162 |             <!-- 不设置时区,则使用镜像的默认时区 -->
163 |             <!-- <TimeZone>China Standard Time</TimeZone> -->
164 |         </component>
165 |     </settings>
166 | </unattend>
167 | 


--------------------------------------------------------------------------------
/wmic.ps1:
--------------------------------------------------------------------------------
 1 | param(
 2 |     [string]$Namespace,
 3 |     [string]$Class,
 4 |     [string]$Filter,
 5 |     [string]$Properties
 6 | )
 7 | 
 8 | $propertiesToDisplay = if ($Properties) { $Properties.Split(",") } else { @("*") }
 9 | 
10 | $wmiQuery = @{
11 |     Namespace = $Namespace
12 |     Class     = $Class
13 | }
14 | 
15 | if ($Filter) {
16 |     $wmiQuery.Filter = $Filter
17 | }
18 | 
19 | Get-WmiObject @wmiQuery | ForEach-Object {
20 |     $_.PSObject.Properties | Where-Object {
21 |         -not $_.Name.StartsWith("__") -and
22 |         ($propertiesToDisplay -contains $_.Name -or $propertiesToDisplay -contains "*")
23 |     } | ForEach-Object {
24 |         $name = $_.Name
25 |         $value = $_.Value
26 | 
27 |         # 改成 wmic 的输出格式
28 |         if ($value -is [Array]) {
29 |             $formattedValue = ($value | ForEach-Object { "`"$_`"" }) -join ","
30 |             Write-Output "$name={$formattedValue}"
31 |         }
32 |         else {
33 |             Write-Output "$name=$value"
34 |         }
35 |     }
36 | }
37 | 


--------------------------------------------------------------------------------