كيفية أتمتة إنشاء الأجهزة الافتراضية؟ نقول بالتفصيل

يعد إنشاء جهاز افتراضي جديد روتينًا مستهلكًا للوقت. والمزيد من البنية التحتية والتنظيم ، والمزيد من الإجراءات المرتبطة بهذه العملية. قمنا بأتمتة هذه العملية باستخدام PowerShell.

مرحبا بكم في كات إذا كنت مهتما.




لا يحب المبرمجون القيام بعمل مزدوج ، كما أن مسؤولي النظام.

فيما يلي مثال لأتمتة أحد عملائنا.

أردنا أن نتأكد من أن أي مهندس أو مدير مشروع يمكنه إنشاء جهاز افتراضي جديد بأقل جهد ولفترة قصيرة. لدى عملائنا نظام ITSM ، في هذا المثال هو ServiceNow ، أنشأنا نموذج الويب المقابل في كتالوج الخدمة. من أجل "طلب" جهاز جديد ، يحتاج المدير إلى ملء الحقول وتأكيد "الطلب" ، وبعد ذلك يتم إطلاق سلسلة العملية ، وعند الإخراج نجهز الآلة للاستخدام.

لذا ، دعنا نلقي نظرة على ما يحتاج المدير إلى تحديده لإنشاء جهاز افتراضي جديد:



وصف الجهاز الظاهري: وصف الجهاز الظاهري
هناك حاجة إلى بعض التوضيحات هنا. في حلنا ، يتم استخدام PowerShell 5.1 بشكل نشط ، لذلك أثناء استخدام نظام Windows فقط ، سنحاول في المستقبل إضافة دعم لأجهزة Unix والتبديل إلى PowerShell Core.

نظام التشغيل ، نظام التشغيل. لا توجد حواجز خاصة لاستخدام Windows 2008 (R2) ، لكننا نستخدم 2012R2 أو 2016.

حجم الجهاز الظاهري ، حجم الجهاز الظاهري. لكل منها ، يمكن تحديد ذلك بطريقته الخاصة ، في هذا المثال صغير 1CPU-4Gb Ram ، متوسط ​​2CPU-8Gb ، كبير 4-16.

تخزين VM ، القرص 0 (C: \) له حجم ثابت لا يمكنك تغييره ، فقط محدد التخزين السريع / البطيء متاح. يمكن أن يكون "سريع" طبقة تخزين مع SSD ، و "بطيء" يمكن تخزينه على محركات الأقراص الصلبة "العادية" (بالطبع ، SAN). يحتوي Disk1 (Disk2 وما بعده) أيضًا على محدد لتحديد التخزين ، بالإضافة إلى الحقول لإدخال الحجم المطلوب بالغيغابايت ، وخطاب القسم وحجم الكتلة (وهو أمر مهم بالنسبة لـ SQL Server).

الثقة ، نحدد أن الجهاز يجب أن يكون مرتبطًا بالمجال أم لا ، مع وصول من الشبكة العامة أم لا.

نوع ونوع الجهاز. يمكن تعريف كل آلة تقريبًا على أنها تطبيق أمامي أو خلفي أو غيرها في جميع الحالات الأخرى. استنادًا إلى النوع المحدد ، يمكننا تحديد الشبكة الفرعية الأكثر ملاءمة للجهاز.

البيئة ، في البنية التحتية للعميل ، يوجد مركزان للبيانات: الرئيسي (الإنتاج) والثانوي (Dev / test) ، DC متصل بواسطة قناة اتصال سريعة ويوفر التسامح مع الخطأ. بموجب الاتفاقية ، تحتوي جميع الأجهزة الافتراضية في Primary DC على عنوان IP يبدأ من 10.230 ، وفي Secondary DC عند 10.231.

(SLA) اتفاقية مستوى الخدمة ، تؤثر هذه المعلمة على جودة الخدمة لهذا الجهاز.

التطبيقات لقد أضفنا القدرة على تثبيت SQL Server وتكوينه. يجب تحديد الإصدار واسم المثيل والترتيب. من الممكن أيضًا تكوين كل من دور خادم الويب وأكثر من ذلك بكثير.

نحتاج الآن إلى تحديد كيفية تخزين القيم المحددة. قررنا أن التنسيق الأكثر ملاءمة هو ملف JSON. كما قلت سابقًا ، تستخدم بيئة العميل خدمة ITSM ServiceNow ؛ المدير ، بعد تحديد جميع القيم الضرورية ، ينقر على زر "الطلب" وبعد ذلك ServiceNow يمرر جميع المعلمات إلى برنامج PowerShell النصي (إلى ServiceNow الخلفي) ، والذي سينشئ ملف JSON. يبدو شيء مثل هذا:

.\CreateConfiguration.ps1 -SecurityZone trusted -VMDescription "VM for CRM System" -Requestor "evgeniy.vpro" -OSVersion 2k16 -OSEdition Standard -BuildNewVM -VMEnvironment Prod -VMServiceLevel GOLD -VMSize Medium -Disk0Tier Fast -Disk1Size 50 -Disk1Tier Eco -Disk1Letter D -MSSQLServer -MSSQLInstanceName "Instance1" -SQLCollation Latin1_General_CI_AS -SQLEdition Standard -Disk2Size 35 -Disk3Size 65 


في نص البرنامج النصي CreateConfiguration .ps1:

 # PowerShell- $config = [ordered]@{} #    . $config.SecurityZone=$SecurityZone 


في النهاية ، قم بتصدير كائننا إلى ملف JSON:

 $ServerConfig = New-Object –TypeName PSObject $config ConvertTo-Json -InputObject $ServerConfig -Depth 100 | Out-File "C:\Configs\TargetNodes\Build\$($Hostname.ToLower()).json" -Force 


تكوين العينة:

 { "Hostname": "dsctest552", "SecurityZone": "trusted", "Domain": "testdomain", "Requestor": "evgeniy.vpro", "VM": { "Size": "Medium", "Environment": "Prod", "SLA": "GOLD", "DbEngine": "MSSQL", "RAM": 8, "Storage": [ { "Id": 0, "Tier": "Fast", "Size": "100", "Allocation": 4, "Letter": "C" }, { "Id": 1, "Tier": "Eco", "Size": 50, "Label": "Data", "Allocation": 64, "Letter": "D" }, { "Id": 2, "Tier": "Fast", "Size": 35, "Label": "Data", "Allocation": 64, "Letter": "E" }, { "Id": 3, "Tier": "Fast", "Size": 65, "Label": "Data", "Allocation": 64, "Letter": "F" } ] }, "Network": { "MAC": "", "IP": "10.230.168.50", "Gateway": "10.230.168.1", "VLAN": “VLAN168” }, "OS": { "Version": "2k16", "Edition": "Standard", "Administrators": [ "LocaAdmin", "testdomain\\ Security-LocalAdmins" ] }, "OU": "OU=Servers,OU=Staging,DC=testdomain", "Applications": [ { "Application": "Microsoft SQL Server 2016", "InstanceName": "vd", "Collation": "Latin1_General_CI_AS", "Edition": "Standard", "Features": "SQLENGINE", "Folders": { "DataRoot": "E:\\MSSQL", "UserDB": "E:\\MSSQL\\MSSQL11.vd\\MSSQL\\Data", "UserLog": "E:\\MSSQL\\MSSQL11.vd\\MSSQL\\Log", "TempDB": "D:\\MSSQL\\MSSQL11.vd\\MSSQL\\TempDB", "TempDBLog": "D:\\MSSQL\\MSSQL11.vd\\MSSQL\\TempDB", "Backup": "E:\\MSSQL\\MSSQL11.vd\\MSSQL\\Backup" }, "MaxMemory": 2147483647 } ], "Description": "VM for CRM", "Certificate": { "File": null, "Thumbprint": null }, "Version": 0 } 


ربما لاحظت أن نموذج الويب لا يحتوي على اسم جهاز افتراضي وعنوان IP. نحصل على هذه القيم تلقائيًا على النحو التالي:

يحتوي اسم الجهاز ، ITSM ServiceNow على قسم خاص: CMDB (قاعدة بيانات إدارة التهيئة) ، تقوم قاعدة البيانات هذه بتخزين جميع السجلات حول الأجهزة الافتراضية الموجودة وحالتها وفريق الدعم والمزيد. لقد أنشأنا حوالي 200 سجل احتياطي بحالة "مُخصص". للحصول على اسم للجهاز الظاهري ، نقوم بتقديم طلب REST لـ CMDB ونحصل على أول سجل "مجاني" ونغير حالته من "مخصص إلى تثبيت معلق".

عنوان IP و VLAN ، قمنا بنشر IPAM على شبكتنا - هذه ميزة مضمنة في Windows Server 2016 تسمح لك بإدارة عناوين IP على شبكتك. ليس من الضروري على الإطلاق استخدام جميع ميزات IPAM (DHCP ، DNS ، AD) ، ولكن لاستخدامها فقط كقاعدة بيانات لعناوين IP مع امتداد محتمل للوظائف. يقدم النص البرمجي الذي ينشئ ملف JSON طلبًا إلى IPAM للحصول على أول عنوان IP مجاني على الشبكة الفرعية. ويتم تحديد الشبكة الفرعية VLAN (الشبكة الفرعية x / 24) استنادًا إلى قيم SLA والبيئة والثقة والنوع المحددة.
ملف التكوين جاهز ، جميع الحقول في مكانها ، يمكنك إنشاء جهاز. السؤال هو "كيفية تخزين بيانات الاعتماد لجميع نصوصنا؟". نستخدم حزمة CredentialManager . تعمل هذه الحزمة مع واجهة برمجة تطبيقات Windows Credential Manager لتخزين كلمات المرور. مثال على إنشاء كلمة مرور:

 New-StoredCredential -Target "ESXi" -UserName "testdomain.eu\vmwareadm" -Password "veryultraP@ssw00rd." -Type Generic -Persist LocalMachine 


ستكون كلمة المرور متاحة للقراءة داخل هذا الجهاز والحساب.

 $ESXiAdmin = Get-StoredCredential -Type Generic -Target ESXi 


لدينا خادم يتم فيه تخزين جميع التكوينات باستخدام GIT ، والآن يمكننا بشكل موثوق تتبع جميع التغييرات في التكوينات: من وماذا وأين ومتى.

يتم تكوين المهمة المجدولة على هذا الخادم: تحقق من المجلد مع التكوينات واكتب في سجل أحداث Windows حول جميع التغييرات.

بعد 15 دقيقة ، ستكتب المهمة المجدولة إلى Windows EventLog أنه تم الكشف عن ملف تكوين جديد.

حان الوقت للتحقق من هذا التكوين. بادئ ذي بدء ، نحتاج إلى التأكد من أن الملف يحتوي على التنسيق الصحيح:

 $Configuration=(Get-Content -Raw $File | Out-String | ConvertFrom-Json) 


إذا كان كل شيء على ما يرام ، فقد حان الوقت لبدء إنشاء الجهاز وتشغيل البرنامج النصي BuildVM.ps1.

في BuildVM.ps1 ، نتحقق من أن ملف التكوين يحتوي على وصف لجميع خصائص الجهاز الظاهري: الحجم ، env ، sla ، النوع ، التخزين ، ram ، الشبكة.

تأكد من التحقق من وجود جهاز بنفس الاسم في البنية التحتية (CheckVM.ps1).
نقوم بالاتصال من خلال VMWare PowerShell CLI بـ vSphere الخاص بنا:

 $VmWareAdmin = Get-StoredCredential -Type Generic -Target ESXi Connect-VIServer -Server "vSphereSrv" -Credential $VmWareAdmin | Out-Null 


تحقق مما إذا كان هناك جهاز بنفس الاسم في البنية التحتية

 $VM=Get-VM $server -ErrorAction SilentlyContinue 


وقم بإيقاف:

 Disconnect-VIServer * -Force -Confirm:$false 


تأكد من أن الجهاز غير متوفر أيضًا على WinRM

 $ping=Test-NetConnection -ComputerName $Configuration.Hostname -CommonTCPPort WINRM -InformationLevel Quiet -ErrorAction SilentlyContinue 


إذا كان $ VM و $ ping فارغين ، فيمكنك إنشاء جهاز جديد. (نحن نتعامل مع المواقف عندما يتم بالفعل إنشاء جهاز يدويًا في ESXi أو يكون هذا الجهاز في مركز بيانات آخر.)

بضع كلمات عن السيارة. هذه صورة آلة افتراضية معدة تم الانتهاء منها بواسطة sysprep وتحويلها إلى قالب في vSphere. يتم حفظ المسؤول المحلي بكلمة المرور المعروفة في الصورة ، ولا يتلف هذا الحساب بعد sysprep ، مما يسمح لنا بالوصول إلى كل جهاز من هذا القالب ، وبعد ذلك يمكننا استبدال كلمة المرور هذه لأغراض أمنية.


إنشاء جهاز افتراضي


ابحث عن مجموعة SLR المقابلة:

 $Cluster=Get-Cluster -Name $Configuration.VM.SLA 


تحقق من وجود مساحة كافية على مخزن البيانات:

 $DatastoreCluster = Get-DatastoreCluster |Where-Object {$_.Name -like $Datastore1Name} $Datastore1 = Get-Datastore -Location $DatastoreCluster |sort -Property "FreeSpaceGB" |select -Last 1 IF ($Datastore1.FreeSpaceGB -le "200"){ Write-Host -foreground red "STOP: Not enough datastore capacity for DISK" $vdisk.Id Break } 


وذاكرة كافية:

 $VMHost = Get-VMHost -Location $Cluster |sort -Property "MemoryUsageGB" |select -First 1 IF ($VMHost.MemoryUsageGB -le "20"){ Write-Host -foreground red "STOP: No enough ESXi host capacity" Break } 


نأخذ قالبنا

 $VMTemplate = Get-Template -Name 'Win2016_Std_x64_Template' 


وإنشاء آلة افتراضية جديدة

 New-VM -Name $Configuration.Hostname.ToUpper() -VMHost $VMHost -ResourcePool $ResourcePool -Datastore $Datastore -Template $VMTemplate -Location "AutoDeployed VMs" 


من المهم توصيل واجهة الشبكة بشبكة فرعية مع تمكين DHCP.

نبدأ الجهاز الظاهري

 Start-VM $VM 


واحفظ وصف الجهاز ، بحيث يمكنك في وقت لاحق تحديد الجهاز على مستوى برنامج VMWare.

 Set-Annotation -Entity $VM -CustomAttribute "Change request" -Value $Configuration.Request -Confirm:$false Set-VM $VM -Notes $Configuration.Description -Confirm:$false 


بدأ تشغيل الجهاز والآن يمكننا معرفة عنوان MAC المستلم:

 $vMAC = (($VM | Get-NetworkAdapter | Select-Object -Property "MacAddress").MacAddress).Replace(':','') 


احفظ هذه القيمة في ملف JSON.

 $Configuration.Network.MAC=$VMAC ConvertTo-Json -InputObject $Configuration -Depth 100 | Out-File "C:\Configs\TargetNodes\Build\$Hostname.json" -Force 


هذا هو الوقت المناسب للالتزام بجهاز Git الخاص بنا الذي تم إنشاء الجهاز به ولديه MAC فريد خاص به.

يبدأ الجهاز في التهيئة (بعد sysprep) ، وإعداد المعدات والتكوين الأولي.

دعنا ننتظر حتى يتوفر جهاز WinRM الخاص بنا مع البرنامج النصي FoundConnection.ps1.

أولاً ، اكتشف ما IP الذي تلقته الآلة من DHCP:

 # $MAC = $vMAC while($isOnline -ne $true){ if((Get-DhcpServerv4Lease -ClientId $MAC -ScopeId $StagingDHCPScope -ComputerName $DHCPServer -ErrorAction Ignore).IPAddress.IPAddressToString){ $tempIP=(Get-DhcpServerv4Lease -ClientId $MAC -ScopeId $StagingDHCPScope -ComputerName $DHCPServer).IPAddress.IPAddressToString break } else{ if($isOnline -ne $true){ Write-Host "`r$i`t" -NoNewline $i++ } } } 


والآن سننتظر ، عندما يكون الجهاز متاحًا على WinRM:

 $LocalAdmin = Get-StoredCredential -Type Generic -Target LocalAdmin $i=0 $isOnline=$false while($isOnline -ne $true){ if(Invoke-Command -ComputerName $tempIP -ScriptBlock{ Get-ItemProperty -Path "Registry::\HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing" } -Credential $LocalAdmin -ErrorAction SilentlyContinue){ $isOnline=$true break } else{ if($isOnline -ne $true){ Write-Host "`r$i" -NoNewline $i++ Start-Sleep -Seconds 1 } } } 


الآلة جاهزة للقيادة.

تكوين الحالة المطلوبة


لتكوين التكوين المطلوب ، نستخدم جزء PowerShell - DSC (تكوين الحالة المرغوبة). يوجد خادم DSC Pull تم تكوينه على الشبكة: dscpull.testdomain.eu.
فيما يلي تكوين خادم سحب DSC الخاص بنا. مقال جيد حول تكوين سحب DSC.

 Node $NodeName { WindowsFeature DSCServiceFeature { Ensure = "Present" Name = "DSC-Service" } xDscWebService PSDSCPullServer { Ensure = "Present" EndpointName = "PSDSCPullServer" Port = 8080 PhysicalPath = "$env:SystemDrive\inetpub\PSDSCPullServer" CertificateThumbPrint = $certificateThumbPrint ModulePath = "$env:PROGRAMFILES\WindowsPowerShell\DscService\Modules" ConfigurationPath = "$env:PROGRAMFILES\WindowsPowerShell\DscService\Configuration" State = "Started" DependsOn = "[WindowsFeature]DSCServiceFeature" RegistrationKeyPath = "$env:PROGRAMFILES\WindowsPowerShell\DscService" AcceptSelfSignedCertificates = $true UseSecurityBestPractices = $true } File RegistrationKeyFile { Ensure = 'Present' Type = 'File' DestinationPath = "$env:ProgramFiles\WindowsPowerShell\DscService\RegistrationKeys.txt" Contents = $RegistrationKey } } 


وهي متاحة على: https://dscpull.testdomain.eu:8080

نقطة النهاية: https://dscpull.testdomain.eu:8080/PSDSCPullserver.svc

يجب تثبيت PowerShell 5.1 على كافة عملاء ملقم السحب
إن لم يكن PowerShell 5.1 مثبتًا:

 $PSVersionTable.PSVersion.Major –lt 5 


تثبيت PowerShell 5.1:

 Write-Host "Download PowerShell 5.1" Invoke-Command -ComputerName $Node -ScriptBlock { [System.Net.ServicePointManager]::SecurityProtocol=[System.Net.SecurityProtocolType]::Tls12;Invoke-WebRequest -Uri "https://dscpull.testdomain.eu:8080/Files/Updates/WMF.msu" -OutFile C:\TEMP\WMF.MSU } Write-Host "Extract PowerShell 5.1" Invoke-Command -ComputerName $Node -ScriptBlock {Start-Process -FilePath 'wusa.exe' -ArgumentList "C:\temp\WMF.msu /extract:C:\temp\" -Wait -PassThru } Write-Host "Apply PowerShell 5.1" Invoke-Command -ComputerName $Node -ScriptBlock {Start-Process -FilePath 'dism.exe' -ArgumentList "/online /add-package /PackagePath:C:\temp\WindowsBlue-KB3191564-x64.cab /Quiet" -Wait -PassThru } Write-Host "PowerShell 5.1 has been installed" 


يتم نشر خادم PKI أيضًا على شبكتنا. هذا شرط للتشفير الآمن لبيانات الاعتماد المخزنة في ملفات msc DSC (ملفات Mof هي "اللغة" التي يتصل بها Pull Server وعملائه). عندما يحاول عميل التسجيل على Pull Server ، من الضروري تحديد شهادة Thumbprint وبعد ذلك على Pull Server سيستخدم هذه الشهادة لتشفير كلمات المرور. أدناه سنرى كيف يعمل.

استيراد CA الجذر إلى الجهاز الجديد الخاص بنا:

  Invoke-Command -ComputerName $server -ScriptBlock{ $PKI="-----BEGIN CERTIFICATE----- MIIF2TCCA8GgAwIBAgIQSPIjcff9rotNdxbg3+ygqDANBgkqhkiG9w0BAQUFADAe **************************************************************** znafMvVx0B4tGEz2PFss/FviGdC3RohBHG0rF5jO50J4nS/3cGGm+HGdn1w/tZd0 a0FWpn9VCOSmXM2It+tSW1f4nZVt6T2kr1ZlTxkDhT7HMSGsrX/XJswzCkDGe3dE qrVVjNUkhVTaeeBWdujB5J6mcx7YkNsAUhODiS9Cf7FnYnxLFA72M0pijI48P5F0 ShM9HWAAUIrLkv13ug== -----END CERTIFICATE-----" $PKI | Out-File RootCA.cer Import-Certificate RootCA.cer -CertStoreLocation Cert:\LocalMachine\Root | select Thumbprint | Out-Null } -Credential $LocalAdmin | Out-Null 


لمزيد من العمل ، نحتاج إلى زوج من مفاتيح RSA. سننشئ شهادة موقعة ذاتيًا ونعمل معها مؤقتًا.

الآن يمكننا التسجيل في Pull Server:

 $DscHostFQDN = [System.Net.Dns]::GetHostEntry([string]$env:computername).HostName $DscPullServerURL = "https://$($DscHostFQDN):8080/PSDSCPullserver.svc" $DscWebConfigChildPath = '\inetpub\psdscpullserver\web.config' $DscWebConfigPath = Join-Path -Path $env:SystemDrive -ChildPath $DscWebConfigChildPath $DscWebConfigXML = [xml](Get-Content $DscWebConfigPath) $DscRegKeyName = 'RegistrationKeys.txt' $DscRegKeyXMLNode = "//appSettings/add[@key = 'RegistrationKeyPath']" $DscRegKeyParentPath = ($DscWebConfigXML.SelectNodes($DscRegKeyXMLNode)).value $DscRegKeyPath = Join-Path -Path $DscRegKeyParentPath -ChildPath $DscRegKeyName $DscRegKey = Get-Content $DscRegKeyPath [DSCLocalConfigurationManager()] configuration RegisterOnPull { Node $Node { Settings { ConfigurationModeFrequencyMins = 1440 CertificateID = $Thumbprint RefreshMode ='Pull' RefreshFrequencyMins = 1440 RebootNodeIfNeeded = $true ConfigurationMode ='ApplyAndAutoCorrect' AllowModuleOverwrite = $true DebugMode = 'None' StatusRetentionTimeInDays = 1 } ConfigurationRepositoryWeb $([string]$env:computername) { ServerURL = $DscPullServerURL RegistrationKey = $DscRegKey CertificateID = $Thumbprint ConfigurationNames = @("$hostx") } } } RegisterOnPull -OutputPath $MetaConfigsStorage Set-DscLocalConfigurationManager -ComputerName $Node -Path $MetaConfigsStorage -Verbose -Force -Credential $LocalAdmin 


أرسل التكوين الأول إلى أجهزتنا

 Configuration Rename { param ( [Parameter()] [System.String[]] $Node, $hostname ) Import-DscResource -ModuleName xComputerManagement Import-DscResource –ModuleName PSDesiredStateConfiguration Node $Node { xComputer JoinDomain { Name = $hostname } } } Rename -Node $Node -OutputPath $DscConfigPath -hostname $hostname New-DscChecksum $DscConfigPath -Force Invoke-Command -ComputerName $Node -ScriptBlock{Update-DscConfiguration -Verbose -Wait } -Credential $LocalAdmin -Verbose 


سيقوم الخادم بإعادة التسمية تلقائيًا وإعادة التشغيل. الآن يمكننا تنفيذ الانضمام إلى المجال.

 Configuration JoinAD { param ( [Parameter()] [System.String[]] $Node, [Parameter(Mandatory = $true)] [ValidateNotNullorEmpty()] [System.Management.Automation.PSCredential] $DomainAdmin, $hostname, $domain ) Import-DscResource -ModuleName xComputerManagement Import-DscResource –ModuleName PSDesiredStateConfiguration Node $Node { xComputer JoinDomain { Name = $hostname DomainName = $domain Credential = $DomainAdmin JoinOU = "OU=Servers,OU=Staging,DC=testdomain,DC=eu" } GroupSet LocalAdmins { GroupName = @( 'Administrators') Ensure = 'Present' MembersToInclude = @( 'testdomain-eu\dscstaging' ) } } } $cd = @{ AllNodes = @( @{ NodeName = $Node PSDscAllowPlainTextPassword = $false PSDscAllowDomainUser=$true Certificatefile = $CertFile Thumbprint = $Certificate.ToString() } ) } JoinAD -Node $Node -OutputPath $DscConfigPath -DomainAdmin $DomainAdmin -hostname $hostname -ConfigurationData $cd -domain $domain New-DscChecksum $DscConfigPath -Force Invoke-Command -ComputerName $Node -ScriptBlock{Update-DscConfiguration -Verbose -Wait } -Credential $LocalAdmin -Verbose 


إليك ما يبدو عليه ملف mof:

 instance of MSFT_Credential as $MSFT_Credential1ref { Password = "-----BEGIN CMS-----\nMIIBsgYJKoZIhvcNAQcDoIIBozCCAZ8CAQAxggFKMIIBRgIBADAuMBoxGDAWBgNVBAMMD1dJTi1H\nNFFKTFFQME4xNQIQOQN77pxew75HU6l7GPn99TANBgkqhkiG9w0BAQcwAASCAQAlhFf7Zs2gJbJEnc1DEK2yWbKcO+BEyD2cr6vKHdn\nQ9TrjvbysEOvYjT15o6MccwkMEwGCSqGSIb3DQEHATAdBglghkgBZQMEASoEEEdKJT+GX4IkPezR\nwYncyQiAIAFKxwJocH4ufRsq9L2Ipkp+VQCx2ljlwif6ac4X/PqG\n-----END CMS-----"; UserName = "testdomain.eu\\service_DomainJoin_001"; }; instance of MSFT_xComputer as $MSFT_xComputer1ref { ResourceID = "[xComputer]JoinDomain"; Credential = $MSFT_Credential1ref; DomainName = "testdomain.eu"; SourceInfo = "C:\\Program Files\\WindowsPowerShell\\Scripts\\JoinAD.ps1::34::9::xComputer"; Name = "dsctest51"; JoinOU = "OU=Servers,OU=Staging,DC=testdomain,DC=eu"; ModuleName = "xComputerManagement"; ModuleVersion = "4.1.0.0"; ConfigurationName = "JoinAD"; }; nMIIBsgYJKoZIhvcNAQcDoIIBozCCAZ8CAQAxggFKMIIBRgIBADAuMBoxGDAWBgNVBAMMD1dJTi1H \ nNFFKTFFQME4xNQIQOQN77pxew75HU6l7GPn99TANBgkqhkiG9w0BAQcwAASCAQAlhFf7Zs2gJbJEnc1DEK2yWbKcO + BEyD2cr6vKHdn \ nQ9TrjvbysEOvYjT15o6MccwkMEwGCSqGSIb3DQEHATAdBglghkgBZQMEASoEEEdKJT + GX4IkPezR \ nwYncyQiAIAFKxwJocH4ufRsq9L2Ipkp + VQCx2ljlwif6ac4X / PqG \ ن ----- END CMS -----". instance of MSFT_Credential as $MSFT_Credential1ref { Password = "-----BEGIN CMS-----\nMIIBsgYJKoZIhvcNAQcDoIIBozCCAZ8CAQAxggFKMIIBRgIBADAuMBoxGDAWBgNVBAMMD1dJTi1H\nNFFKTFFQME4xNQIQOQN77pxew75HU6l7GPn99TANBgkqhkiG9w0BAQcwAASCAQAlhFf7Zs2gJbJEnc1DEK2yWbKcO+BEyD2cr6vKHdn\nQ9TrjvbysEOvYjT15o6MccwkMEwGCSqGSIb3DQEHATAdBglghkgBZQMEASoEEEdKJT+GX4IkPezR\nwYncyQiAIAFKxwJocH4ufRsq9L2Ipkp+VQCx2ljlwif6ac4X/PqG\n-----END CMS-----"; UserName = "testdomain.eu\\service_DomainJoin_001"; }; instance of MSFT_xComputer as $MSFT_xComputer1ref { ResourceID = "[xComputer]JoinDomain"; Credential = $MSFT_Credential1ref; DomainName = "testdomain.eu"; SourceInfo = "C:\\Program Files\\WindowsPowerShell\\Scripts\\JoinAD.ps1::34::9::xComputer"; Name = "dsctest51"; JoinOU = "OU=Servers,OU=Staging,DC=testdomain,DC=eu"; ModuleName = "xComputerManagement"; ModuleVersion = "4.1.0.0"; ConfigurationName = "JoinAD"; }; 


تشفير DSC بيانات الاعتماد من حساب خدمة له حقوق مسؤول المجال: testdomain.eu \\ service_DomainJoin_001 مع شهادة موقعة ذاتيًا. يقوم عميل DSC بمفتاحه الخاص بفك تشفير بيانات الاعتماد وتطبيق جميع وحدات التكوين مع بيانات اعتماد المجال المحددة. في هذه الحالة ، ينفذ الانضمام إلى المجال في الوحدة التنظيمية المحددة.

 GroupSet LocalAdmins { GroupName = @( 'Administrators') Ensure = 'Present' MembersToInclude = @( testdomain-eu\dscstaging' ) } 


تضيف هذه الوحدة dscstaging إلى المسؤولين المحليين لمزيد من التكوين.

بعد إعادة التشغيل ، سنتمكن من دخول الجهاز باستخدام بيانات اعتماد المجال.

نحن في انتظار أن يتلقى الخادم شهادة من PKI (لدينا تكوين تسجيل تلقائي) وفي المستقبل سنعمل مع الشهادة الصادرة عن PKI الخاص بنا.

 $vmcert=Invoke-Command -ComputerName $server -ScriptBlock{ return Get-ChildItem -Path cert:\LocalMachine\My | where {$_.EnhancedKeyUsageList.FriendlyName -eq "Document Encryption"-and $_.Issuer -eq "CN=TestDomain Issuing CA, DC=testdomain, DC=eu"} } -ErrorAction Ignore 


اشترك الآن في Pull Server مرة أخرى باستخدام بصمة الإبهام المحدثة.

هذا كل شيء ، الجهاز المرتبط بالمجال ، ويمكننا استخدامه بالطريقة التي تناسبنا.

قم بتثبيت SQL Server


يصف ملف JSON متطلبات MS SQL Server ، كما نستخدم DSC لتثبيت SQL Server وتكوينه. هذا ما يبدو عليه التكوين:

 Configuration $Node{ WindowsFeature "NetFramework35"{ Name = "NET-Framework-Core" Ensure = "Present" Source = "\\$DscHostFQDN\Files\Updates" } WindowsFeature "NetFramework45"{ Name = "NET-Framework-45-Core" Ensure= "Present" } SqlSetup "MSSQL2012NamedInstance"{ InstanceName = $MSSQL.InstanceName Features = $MSSQL.Features ProductKey = $ProductKey SQLCollation = $MSSQL.Collation SQLSysAdminAccounts = @('testdomain-EU\SQLAdmins',' testdomain-EU\Backup') InstallSharedDir = "C:\Program Files\Microsoft SQL Server" InstallSharedWOWDir = "C:\Program Files (x86)\Microsoft SQL Server" InstallSQLDataDir = $MSSQL.DataRoot SQLUserDBDir = $MSSQL.UserDBDir SQLUserDBLogDir = $MSSQL.UserLogDir SQLTempDBDir = $MSSQL.TempDBDir SQLTempDBLogDir = $MSSQL.TempDBLogDir SQLBackupDir = $MSSQL.BackupDir SourcePath = $SQLSource SAPwd = $SA SecurityMode = 'SQL' UpdateSource = ".\Updates" Action = "Install" ForceReboot = $True SQLSvcAccount = $SqlServiceCredential AgtSvcAccount = $SqlServiceCredential ISSvcAccount = $SqlServiceCredential BrowserSvcStartupType = "Automatic" DependsOn = '[WindowsFeature]NetFramework35', '[WindowsFeature]NetFramework45' } 

حيث يتم تعريف $ MSSQL:
 $MSSQL=$Configuration.Applications | where {$_.Application -eq "Microsoft SQL Server 2012"} 


$ MSSQL.InstanceName - كل هذا موضح في ملف Json الخاص بنا. سيؤدي تطبيق هذا التكوين إلى تثبيت MS SQL Server مع جميع التحديثات في مجلد التحديثات وإعادة تشغيل الخادم إذا لزم الأمر.

السيارة جاهزة.

الخدمة الآن


هناك العديد من واجهات برمجة التطبيقات المتاحة في Service-Now. نحن نستخدم Rest API.
للحصول على قائمة بالآلات ذات الحالة المخصصة ، يتم استخدام استعلام النموذج:
example.service-now.com/cmdb_ci_server_list.do؟sysparm_query=install_status=16 ^ u_subtype = ^ ORDERBYname
في PowerShell ، يبدو الأمر كما يلي:
 $url="https://instance.service-now.com/api/now/table/cmdb_ci_server?sysparm_query=install_status=16^u_subtype=^ORDERBYname" $uri= new-object System.Uri("https://instance.service-now.com/") #       $credentials = (Get-StoredCredential -Type Generic -Target DSC).GetNetworkCredential() $credentials = new-object System.Net.NetworkCredential $credentials.UserName, $credentials.SecurePassword Add-Type -AssemblyName System.Net.Http $handler = New-Object System.Net.Http.HttpClientHandler $handler.CookieContainer = New-Object System.Net.CookieContainer $handler.UseCookies=$true $handler.Credentials=$credentials $HttpClient = New-Object System.Net.Http.HttpClient($handler) $HttpClient.BaseAddress= $uri $Header = New-Object System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json") $HttpClient.DefaultRequestHeaders.Accept.Clear() $HttpClient.DefaultRequestHeaders.Accept.Add($Header); $response=$HttpClient.GetAsync($url) $respStream=$response.Result.Content.ReadAsStringAsync() $Servers = $respStream.Result | ConvertFrom-Json #   Configuration Items  $ServersCI=$Servers.result 

كائن الصفيف الأول هو اسم المضيف الذي نحتاجه.
إذا كان الجهاز جاهزًا ، فيمكنك تغيير حالة الجهاز في Service-Now ، لهذا البرنامج النصي UpdateCI.ps1:
 param( $CI, [ValidateSet("Allocated","In use","Pending install")] $NewStatus='In use' ) $url="https://instance.service-now.com/api/now/table/cmdb_ci_server?sysparm_query=name=$CI" $uri= new-object System.Uri("https://instance.service-now.com/") $credentials = (Get-StoredCredential -Type Generic -Target DSC).GetNetworkCredential() $credentials = new-object System.Net.NetworkCredential $credentials.UserName, $credentials.SecurePassword Add-Type -AssemblyName System.Net.Http $handler = New-Object System.Net.Http.HttpClientHandler $handler.CookieContainer = New-Object System.Net.CookieContainer $handler.UseCookies=$true $handler.Credentials=$credentials $HttpClient = New-Object System.Net.Http.HttpClient($handler) $HttpClient.BaseAddress= $uri $Header = New-Object System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json") $HttpClient.DefaultRequestHeaders.Accept.Clear() $HttpClient.DefaultRequestHeaders.Accept.Add($Header); $response=$HttpClient.GetAsync($url) $respStream=$response.Result.Content.ReadAsStringAsync() $Servers = $respStream.Result | ConvertFrom-Json $ServerCI=$Servers.result[0] $update=@{} if($NewStatus -eq "In use"){ $update.install_status=1 } if($NewStatus -eq "Pending install"){ $update.install_status=4 } $stringcontent = New-Object System.Net.Http.StringContent((ConvertTo-Json -InputObject $update -Depth 100),[System.Text.Encoding]::UTF8, "application/json"); $result=$HttpClient.PutAsync("https://instance.service-now.com/api/now/table/cmdb_ci_server/$($ServerCI.sys_id)", $stringcontent) 

للحصول على الجدول والسجلات ، يتم استخدام طلبات RET API GET ، لتغيير طلبات التسجيل PUT / POST ، التي تحتاج إلى تغيير حقولها في النص.

لقد أنشأنا أداة مناسبة باستخدام أداة رسومية مثل Azure Portal ، والتي تتيح لنا إدارة البنية التحتية الداخلية قدر الإمكان لنا ولعملائنا.
PS 12.24.2018. هل يبدو أن كل شيء قديم؟ حان الوقت لاستخدام Azure DevOps. في المقالة التالية ، سأوضح لك كيفية القيام بكل هذا مع خط أنابيب Azure DevOps.

Source: https://habr.com/ru/post/ar425129/


All Articles