【虚拟机管理】批量创建Vsphere虚拟机脚本
1 环境准备
- 一台Linux服务器,已经部署好jenkins、powershell-for-Linux以及powerCLI插件
- jenkins优化:已配置ssh到宿主机的免密功能
- 代码文件 http://git.mrzsir.cn/mrzsir/create-vh.git
2 编辑ps1脚本
- 通过脚本调用csv参数表,批量循环创建
#导入表格变量 2)模板网卡名 2)模板账号密码
$vms = Import-CSV ./VM.csv
$templatenic = 'ens192'
$templateuser = '模板账号'
$templatepass = '模板密码'
#测试变量语句
$cmd = 'cmdecho111111111111111111111111'
#连接Vcenter认证信息
Connect-VIServer -Protocol https -User 'administrator@你的SSO_NAME.cn' -Password '你的Vcenter密码' -Server Vcenter_IP
#循环取值
foreach ($vm in $vms){
#主机名,不是OS主机名
$VMName = $vm.Name
#网络
$Network = $vm.Network
#虚拟cpu
$Cpu = $vm.Cpu
#内存单位GB
$Memory = $vm.Memory
#虚拟机备注
$Notes = $vm.Usage
#新增磁盘
$Disk = $vm.DISK
#使用的模板
$Template = Get-Template $vm.Template
#所在ESXI物理主机IP
$VMHost = Get-VMHost $vm.PhysicalHost
#使用的存储名
$Datastore = Get-Datastore $vm.Datastore
#放到哪个文件夹中
New-Folder -Name $vm.Esxidir -Location VM
#等待5s
Start-Sleep -s 5
#使用上面的变量创建虚拟机
New-VM -Name $VMName -Template $Template -VMHost $VMHost -NetworkName $Network -Datastore $Datastore -RunAsync -Location $vm.Esxidir
#等待30s
Start-Sleep -s 30
#设置内存 CPU 备注
Get-VM -Name $VMName|Set-VM -NumCPU $Cpu -MemoryGB $Memory -Notes $Notes -Confirm:$false
Start-Sleep -s 5
#如果$DISK值不为0,就创建一个磁盘(厚制备延迟置0)
if ($Disk -gt 0)
{ Get-VM -Name $VMName | New-HardDisk -CapacityGB $Disk -Persistence persistent }
Start-Sleep -s 5
#启动虚拟机
Get-VM $VMName| Start-VM
Start-Sleep -s 20
#变量测试语句
#$vmcfg='echo '+$cmd+' > /tmp/test.txt && echo '+$cmd+' && \
#echo 123testetste'
#系统初始化脚本:1)主机名2)网卡配置
$vmcfg='hostnamectl set-hostname '+$VMName+' ;bash && \
sed -i "/^IPADDR/c\IPADDR='+$vm.IPV4+'" /etc/sysconfig/network-scripts/ifcfg-'+$templatenic+' && \
sed -i "/^NETMASK/c\NETMASK='+$vm.NetMask+'" /etc/sysconfig/network-scripts/ifcfg-'+$templatenic+' && \
sed -i "/^GATEWAY/c\GATEWAY='+$vm.IPV4GW+'" /etc/sysconfig/network-scripts/ifcfg-'+$templatenic+' && \
sed -i "/^DNS1/c\DNS1=223.5.5.5" /etc/sysconfig/network-scripts/ifcfg-'+$templatenic+' && \
echo "DNS2=223.6.6.6" >> /etc/sysconfig/network-scripts/ifcfg-'+$templatenic+' && \
echo "DNS3=119.29.29.29" >> /etc/sysconfig/network-scripts/ifcfg-'+$templatenic+' && \
cat /etc/sysconfig/network-scripts/ifcfg-'+$templatenic+' && \
/etc/init.d/network restart'
#使用模板的账号密码登录新建的虚拟机OS并执行sh脚本
Get-VM $VMName | Invoke-VMScript -ScriptText $vmcfg -GuestUser $templateuser -GuestPassword $templatepass
}
3 编辑参数变量表
- 具体参数对应可在ps脚本中查找
4 使用Go http实现上传csv表文件到Linux服务器
- 代码需要修改IP为服务器IP后在编译成二进制包,nohup到后台运行即可
- 默认上传到 /tmp 目录下,可以根据实际情况修改,注意这里的csv文件名是固定值 "VM.csv"
package main
import (
"crypto/rand"
"fmt"
"html/template"
"io/ioutil"
"log"
"net/http"
"os"
"path/filepath"
)
//文件限制2MB
const maxUploadSize = 2 * 1024 * 1024 // 2 mb
var uploadPath = os.TempDir()
func main() {
http.HandleFunc("/upload", uploadFileHandler())
fs := http.FileServer(http.Dir(uploadPath))
http.Handle("/files/", http.StripPrefix("/files", fs))
log.Print("Server started on 你自己的服务器IP:8083, use /upload for uploading files and /files/{fileName} for downloading")
log.Fatal(http.ListenAndServe(":8083", nil))
}
func uploadFileHandler() http.HandlerFunc {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method == "GET" {
t, _ := template.ParseFiles("upload.gtpl")
t.Execute(w, nil)
return
}
if err := r.ParseMultipartForm(maxUploadSize); err != nil {
fmt.Printf("Could not parse multipart form: %v\n", err)
renderError(w, "CANT_PARSE_FORM", http.StatusInternalServerError)
return
}
file, fileHeader, err := r.FormFile("uploadFile")
if err != nil {
renderError(w, "INVALID_FILE", http.StatusBadRequest)
return
}
defer file.Close()
fileSize := fileHeader.Size
fmt.Printf("File size (bytes): %v\n", fileSize)
if fileSize > maxUploadSize {
renderError(w, "FILE_TOO_BIG", http.StatusBadRequest)
return
}
fileBytes, err := ioutil.ReadAll(file)
if err != nil {
renderError(w, "INVALID_FILE", http.StatusBadRequest)
return
}
//这个csv表格设置为你自己的名字
fileName := "VM.csv"
newFileName := fileName
newPath := filepath.Join(uploadPath, newFileName)
fmt.Printf("FileType: %s, File: %s\n", newPath)
newFile, err := os.Create(newPath)
if err != nil {
renderError(w, "CANT_WRITE_FILE", http.StatusInternalServerError)
return
}
defer newFile.Close()
if _, err := newFile.Write(fileBytes); err != nil || newFile.Close() != nil {
renderError(w, "CANT_WRITE_FILE", http.StatusInternalServerError)
return
}
w.Write([]byte(fmt.Sprintf("SUCCESS - use /files/%v to access the file", newFileName)))
})
}
func renderError(w http.ResponseWriter, message string, statusCode int) {
w.WriteHeader(statusCode)
w.Write([]byte(message))
}
func randToken(len int) string {
b := make([]byte, len)
rand.Read(b)
return fmt.Sprintf("%x", b)
}
- 网页模板代码 upload.gtpl
<html>
<head>
<title>Upload file</title>
</head>
<body>
<form enctype="multipart/form-data" action="http://你的服务器IP:8083/upload" method="post">
<input type="file" name="uploadFile" />
<input type="submit" value="upload" />
</form>
</body>
</html>
- 访问地址与效果
5 使用jenkins发布任务
- 编辑文件后通过网页api上传到linux服务器的/tmp/ 目录下后使用jenkins执行后台任务
- 流水线参考
pipeline {
agent any
stages {
stage('构建') {
parallel{
stage('构建步骤-1-test') {
steps {
sh 'echo 开始构建步骤_1 ...'
}
}
stage('创建虚拟机中') {
steps {
sh 'ssh root@你的服务器IP "cd /data/psh-create-host/many-create && yes|cp -r -f /tmp/VM.csv /data/psh-create-host/many-create && pwsh /data/psh-create-host/many-create/VM.ps1 >> create.log "'
}
}
}
}
stage('测试'){
steps {
sh 'echo 开始测试 ...'
}
}
stage('发布') {
steps {
sh 'echo 开始发布 ...'
}
}
}
}
- 效果图
转载请注明-MrZ-个人博客
THE END
0
二维码
海报
【虚拟机管理】批量创建Vsphere虚拟机脚本
1 环境准备
一台Linux服务器,已经部署好jenkins、powershell-for-Linux以及powerCLI插件
jenkins优化:已配置ssh到宿主机的免密功能
代码文件 http://git.mrzsir.cn/mrzsir/create-vh.git
2 编辑ps1脚本
通过……



共有 0 条评论